Processing ambiguous types in composite free DSL files

I am creating a pair of DSLs that should be combined on the basis of “free monads” and “datatypes a la carte” using free and compdata packages (similar in spirit to the Unification of free types ).

While this works for some simple DSLs, I am stuck with one that has a type parameter in the case of a constructor / command that is independent of this type parameter, causing an ambiguous type error with GHC.

To clarify, here is the code:

{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeOperators #-}

module DSL where

import Data.Comp
import Control.Monad.Free

type Index = Int

data DSL a next = Read Index (a -> next)
                | Write a (Index -> next)
                | GetLastIndex (Index -> next)
    deriving (Functor)

read :: (Functor f, DSL a :<: f, MonadFree f m) => Index -> m a
read idx = liftF (inj (Read idx id))

write :: (Functor f, DSL a :<: f, MonadFree f m) => a -> m Index
write a = liftF (inj (Write a id))

-- This works
getLastIndex' :: MonadFree (DSL a) m => m Index
getLastIndex' = liftF (GetLastIndex id)

-- This doesn't:
--
--     Could not deduce (Data.Comp.Ops.Subsume
--                         (compdata-0.10:Data.Comp.SubsumeCommon.ComprEmb
--                            (Data.Comp.Ops.Elem (DSL a0) f))
--                         (DSL a0)
--                         f)
--     from the context (Functor f, DSL a :<: f, MonadFree f m)
--       bound by the type signature for
--                  getLastIndex :: (Functor f, DSL a :<: f, MonadFree f m) => m Index
--       at simple.hs:30:17-66
--     The type variable ‘a0’ is ambiguous
--     In the ambiguity check for the type signature for ‘getLastIndex’:
--       getLastIndex :: forall (m :: * -> *) (f :: * -> *) a.
--                       (Functor f, DSL a :<: f, MonadFree f m) =>
--                       m Index
--     To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
--     In the type signature for ‘getLastIndex’:
--       getLastIndex :: (Functor f, DSL a :<: f, MonadFree f m) => m Index

getLastIndex :: (Functor f, DSL a :<: f, MonadFree f m) => m Index
-- getLastIndex = liftF (inj (GetLastIndex id))
getLastIndex = _

Trying to get this to work by enabling the AllowAmbiguousTypes extension, as the GHC hinted at, did not call me. I tried to add some a-style stuff in the signature type, but to no avail.

Is there any way to make this template work?

+4
1

"à la Carte".

, f, , , .

, , , a DSL () a DSL Int. GHC , getLastIndex, a . GHC a .

, Data.Proxy:

import Data.Proxy

getLastIndex ::
  forall a f m.
  (Functor f, DSL a :<: f, MonadFree f m)
  => Proxy a -> m Index
getLastIndex _ = liftF (inj (GetLastIndex id :: DSL a Index))

, , , DSL. :<: , DSL (, ). compdata , .

, , . , . , - . ; , , - Write x f, x , .

, , ! DSL a b next, DSL '(a, b) next.

+3
source

All Articles