[Haskell-cafe] Strange "ambiguity" problems thanks to GADTs
Oleg Grenrus
oleg.grenrus at iki.fi
Wed Jul 22 07:53:09 UTC 2015
Nailing down `abt` and `abt’`, but keeping `a` free makes the trick:
{-# LANGUAGE DataKinds, PolyKinds, GADTs, RankNTypes, ScopedTypeVariables #-}
data Type = Fun Type Type | Unit
data Sing :: Type -> * where
SUnit :: Sing Unit
SFun :: Sing i -> Sing j -> Sing (Fun i j)
data AST :: (Type -> *) -> Type -> * where
TT :: AST ast Unit
App :: ast (Fun a b) -> ast a -> AST ast b
class ABT (abt :: Type -> *) where
view :: abt a -> AST abt a
unview :: AST abt a -> abt a
class WellTypedABT (abt :: Type -> *) where
unviewWT :: Sing a -> AST abt a -> abt a
typeOf :: abt a -> Sing a
type TypeCheckMonad = Maybe
inferType
:: forall abt abt' a. (ABT abt, WellTypedABT abt')
=> abt a
-> TypeCheckMonad (abt' a)
inferType e0 = go e0
-- b is free, abt and abt' are bounded, class dictionaries come from above.
where go :: forall b. abt b -> TypeCheckMonad (abt' b)
go e0' = case view e0' of
TT -> return . unviewWT SUnit $ TT
App e1 e2 -> do
e1' <- go e1
case typeOf e1' of
-- -Wall doesn't warn about missing SUnit case here, victory!
SFun _typ2 typ3 -> do
e2' <- inferType e2
return . unviewWT typ3 $ App e1' e2'
> On 07 Jul 2015, at 19:05, wren romano <winterkoninkje at gmail.com> wrote:
>
> On Tue, Jul 7, 2015 at 3:35 AM, Simon Peyton Jones
> <simonpj at microsoft.com> wrote:
>> If you post a repro case someone (even me) might help. The devil is always in the details.
>
> The smallest repro I can come up with (which is still related to the
> actual problem) is as follows. In case it matters for the solution,
> there are a number of important bits I've erased. Most importantly,
> the inferType function is actually mutually recursive with a checkType
> function, though that doesn't seem to be the cause of the problem.
>
>
> {-# LANGUAGE DataKinds, PolyKinds, GADTs #-}
>
> data Type = Fun Type Type
>
> data Sing :: Type -> * where
> SFun :: Sing i -> Sing j -> Sing (Fun i j)
>
> data AST :: (Type -> *) -> Type -> * where
> App :: ast (Fun a b) -> ast a -> AST ast b
>
> class ABT (abt :: Type -> *) where
> view :: abt a -> AST abt a
> unview :: AST abt a -> abt a
>
> class WellTypedABT (abt :: Type -> *) where
> unviewWT :: Sing a -> AST abt a -> abt a
> typeOf :: abt a -> Sing a
>
> data TypeCheckMonad a = TCM { unTCM :: a }
>
> instance Functor TypeCheckMonad where
> fmap f = TCM . f . unTCM
>
> instance Applicative TypeCheckMonad where
> pure = TCM
> TCM f <*> TCM x = TCM (f x)
>
> instance Monad TypeCheckMonad where
> return = pure
> TCM x >>= k = k x
>
> inferType
> :: (ABT abt, WellTypedABT abt')
> => abt a
> -> TypeCheckMonad (abt' a)
> inferType e0 =
> case view e0 of
> App e1 e2 -> do
> e1' <- inferType e1
> case typeOf e1' of
> SFun typ2 typ3 -> do
> e2' <- inferType e2
> return . unviewWT typ3 $ App e1' e2'
> --
> Live well,
> ~wren
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 842 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20150722/f66b9c37/attachment.sig>
More information about the Haskell-Cafe
mailing list