使用类型同义词的函数定义“比预期的更少多态”

时间:2012-08-20 13:21:01

标签: haskell types polymorphism ghci

鉴于此类型的同义词:

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时,这两个定义都有效。

这是什么问题?我已多次遇到这个问题,但从未理解为什么。

P.S。我试过了:set -XNoMonomorphismRestriction,但这并没有什么区别。

1 个答案:

答案 0 :(得分: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也不起作用。)