Generalizing from a specific type to a class in a GADT

空扰寡人 提交于 2020-01-24 00:41:04

问题


I have the following definitions

{-# LANGUAGE GADTs, TypeInType, RankNTypes #-}
import Data.Kind

class Character (a :: * -> *) where
  showVal :: a b -> b -> String

data ExampleCharacter a where
  Variable :: ExampleCharacter String
  EqualSign :: ExampleCharacter ()
  Deref :: ExampleCharacter ()

instance Character ExampleCharacter where
  showVal Variable = id
  showVal EqualSign = const "="
  showVal Deref = const "*"

data Symbol :: forall a. ExampleCharacter a -> * where
  Terminal :: a -> Symbol (b :: ExampleCharacter a)

as you can see I have defined a Symbol class that uses ExampleCharacters in the type signature. Example usage would be let sym = Terminal "xyy" :: Symbol Variable creating a variable symbol with the name "xyy".

Now, the obvious next step would be to generalize ExampleCharacter to Character c. I tried the following:

data Symbol :: (forall c (a :: *). Character c) => c a -> * where
  Terminal :: a -> Symbol (b :: c a)

But I get the following error:

main.hs:22:20: error:
    • Illegal constraint in a type: forall (c :: * -> *) a. Character c
    • In the type ‘Symbol (b :: c a)’
      In the definition of data constructor ‘Terminal’
      In the data declaration for ‘Symbol’

I'm not quite sure what the error wants to tell me. Why is forall (c :: * -> *) a. Character c an illegal constraint and how so? Is there any way around it?


回答1:


From the docs:

As kinds and types are the same, kinds can now (with -XTypeInType) contain type constraints. Only equality constraints are currently supported, however. We expect this to extend to other constraints in the future.

So in principle what you've written is sensible; it simply isn't supported yet (as of writing, most recent GHC is 8.2.2).



来源:https://stackoverflow.com/questions/48313174/generalizing-from-a-specific-type-to-a-class-in-a-gadt

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!