1

我有以下数据类型:

{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE ExtendedDefaultRules #-}

class ToString a where

data M = forall a. (ToString a) => B a

在 GHCI 中,我可以毫无问题地执行以下操作:

let bs = [B, B]

但是,如果我尝试在已编译的文件中执行此操作,则会收到以下错误:

No instance for (ToString a0) arising from a use of ‘B’
The type variable ‘a0’ is ambiguous
Relevant bindings include
  bs :: [a0 -> M] (bound at src/My/Module:7:1)

我错过了哪些扩展名,可以让我创建B如图所示的列表?或者我错过了 GHCI 添加的内容?

4

1 回答 1

4

这是因为 GHCi 没有开启单态限制,而 GHC(默认情况下)会开启。为了见证,以下文件类型检查:

{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE NoMonomorphismRestriction #-}

class ToString a where

data M = forall a. (ToString a) => B a

bs = [B, B]

当然,推断的类型bs是相当无用的:

*Main> :t bs
bs :: ToString a => [a -> M]

如果您不想关闭单态限制,您可以在定义中添加类型签名bs

{-# LANGUAGE ExistentialQuantification #-}

class ToString a where

data M = forall a. (ToString a) => B a

bs :: (ToString a) => [a -> M]
bs = [B, B]
于 2016-09-07T04:31:55.673 回答