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

Mat*_*ick 4 polymorphism haskell types ghci

鉴于此类型的同义词:

type Synonym a b = (a, b)
Run Code Online (Sandbox Code Playgroud)

此代码在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
Run Code Online (Sandbox Code Playgroud)

但这样做:

ghci> let myFirst = fst :: Synonym a b -> a
-- no problem --
Run Code Online (Sandbox Code Playgroud)

这只有在我直接输入GHCi时才会发生; 当我将它们放入文件和:load它们时,这两个定义都有效.

这里有什么问题?我多次遇到这个问题,但从未理解为什么.

ps我试过:set -XNoMonomorphismRestriction,但这没有什么区别.

huo*_*uon 9

Haskell试图匹配类型签名f,而不是myFirst,并且它不起作用(我不能给出更多的解释,但是,其他人?).即Haskell将其视为:

let myFirst (f,s) = (f :: Synonym a b -> a)
Run Code Online (Sandbox Code Playgroud)

您可以修复此问题,给出单独的签名

let myFirst :: Synonym a b -> a; myFirst (f,s) = f
Run Code Online (Sandbox Code Playgroud)

甚至使用lambda(这基本上等同于myFirst = fst定义)

let myFirst = (\(f,s) -> f) :: Synonym a b -> a
Run Code Online (Sandbox Code Playgroud)

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