0

我有以下定义

{-# 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)

如您所见,我已经定义了一个 Symbol 类,它在类型签名中使用 ExampleCharacters。示例用法是使用let sym = Terminal "xyy" :: Symbol Variable名称创建变量符号"xyy"

现在,显而易见的下一步是推广ExampleCharacterCharacter c. 我尝试了以下方法:

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

但我收到以下错误:

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’

我不太确定错误想告诉我什么。为什么是forall (c :: * -> *) a. Character c非法约束以及如何呢?有什么办法吗?

4

1 回答 1

2

文档

由于种类和类型相同,种类现在可以(使用 -XTypeInType)包含类型约束。但是,目前仅支持等式约束。我们预计这将在未来扩展到其他限制。

所以原则上你写的东西是明智的;它根本不支持(截至撰写本文时,最新的 GHC 是 8.2.2)。

于 2018-01-18T23:22:20.113 回答