使用类型同义词定义函数时,其“多态性不如预期”。

4

考虑下面这个类型同义词:

type Synonym a b = (a, b)

这个代码在GHCi中无法运行:

ghci> let myFirst (f, s) = f :: Synonym a b -> a

<interactive>:1:21:
    Inferred type is less polymorphic than expected
      Quantified type variable `b' is mentioned in the environment:
        f :: Synonym a b -> a (bound at <interactive>:1:13)
      Quantified type variable `a' is mentioned in the environment:
        f :: Synonym a b -> a (bound at <interactive>:1:13)
    In the expression: f :: Synonym a b -> a
    In the definition of `myFirst':
        myFirst (f, s) = f :: Synonym a b -> a

但是这项技术可以:
ghci> let myFirst = fst :: Synonym a b -> a
-- no problem --

当我直接在GHCi中输入时,只有第一个定义有效;但是当我将它们放在文件中并使用:load命令加载时,两个定义都有效。
这里的问题是什么?我遇到过很多次这个问题,但从未理解过为什么会出现这种情况。
附:我尝试过:set -XNoMonomorphismRestriction,但没有任何变化。
1个回答

9

Haskell试图将类型签名与f匹配,而不是与myFirst匹配,但它无法正常工作(虽然我无法给出更多的解释,需要其他人来解答)。也就是说,Haskell将其视为:

let myFirst (f,s) = (f :: Synonym a b -> a)

您可以通过提供单独的签名来解决此问题。
let myFirst :: Synonym a b -> a; myFirst (f,s) = f

甚至可以使用lambda表达式(这本质上等同于myFirst = fst的定义)

let myFirst = (\(f,s) -> f) :: Synonym a b -> a

(请注意,即使没有类型同义词,这也会失败:let myFirst (f,s) = f :: (a,b) -> a也不起作用。)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接