使用DataKinds时,无法在GHCI中指定类型签名

m-r*_*aud 6 haskell data-kinds

所以,当我尝试在使用时确定多态返回值的类型时,ghci给了我一个有趣的错误DataKinds.我有以下代码:

{-# LANGUAGE DataKinds #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE StandaloneDeriving #-}

data DataKind
    = KindA
    | KindB

data SomeData (a :: DataKind) = forall c. SomeData
    { val :: Int
    , sub :: Maybe (SomeData c)
    }

deriving instance Show (SomeData a)

two :: SomeData 'KindA
two = SomeData 2 Nothing
Run Code Online (Sandbox Code Playgroud)

此代码按预期编译.如果我SomeData在ghci中构造并且没有指定类型它可以正常工作:

> two
SomeData {val = 2, sub = Nothing}

> :t two
two :: SomeData 'KindA

> SomeData 2 Nothing
SomeData 2 Nothing :: SomeData a
Run Code Online (Sandbox Code Playgroud)

但是,如果我尝试指定它错误的类型:

> SomeData 2 Nothing :: SomeData 'KindA
<interactive>:745:32-37: error:
• Data constructor ‘KindA’ cannot be used here
    (Perhaps you intended to use DataKinds)
• In the first argument of ‘SomeData’, namely ‘KindA’
  In an expression type signature: SomeData KindA
  In the expression: SomeData 1 Nothing :: SomeData KindA
Run Code Online (Sandbox Code Playgroud)

似乎报价不是由ghci解释的.我开始使用repl stack ghci.有没有人遇到过这个?在此先感谢您的帮助.

rya*_*hza 10

SomeData 2 Nothing :: SomeData 'KindA如果你第一个工作:seti -XDataKinds.我的想法是在加载文件时合并代码文件中的编译指示,但是对于在REPL中评估的内容,您还需要在GHCi中明确地启用它们.

我认为这就像在GHCi中一样,你加载的文件更像是导入的模块,REPL中的任何代码都有自己的一组语言扩展.在GHCi中加载多个文件时,您可能不一定希望启用/可用所有加载文件中的所有语言扩展.

  • 使用`:seti`代替`:set`通常更好 - 使用`:set`将*也*导致在所有加载的文件*中启用扩展,就好像你用这些选项运行`ghc`一样.`:seti`命令只是*set*s*i*nteractive使用的扩展名.例如,GHCi的行为就像用户默认指定`:seti -XNoMonomorphismRestriction`一样 - GHCi绑定变量不是单形的,但加载文件中绑定的变量是单独存在的. (3认同)