为什么Haskell函数声明中的拼写错误导致GHCi在先前编译的代码周围抛出错误?

Joe*_*ick 10 haskell ghci

这是一个奇怪的问题.通过LearnYouaHaskell学习Haskell,很棒的书,我正在实施各种例子.

这在GHCi中编译

cylinder :: (RealFloat a) => a -> a -> a
cylinder r h =
    let sideArea = 2 * pi * r * h
    topArea = pi * r ^2
    in  sideArea + 2 * topArea
Run Code Online (Sandbox Code Playgroud)

这在GHCi中编译

zipWith' :: (a -> b -> c) -> [a] -> [b] -> [c]  
zipWith' _ [] _ = []  
zipWith' _ _ [] = []  
zipWith' f (x:xs) (y:ys) = f x y : zipWith' f xs ys 
Run Code Online (Sandbox Code Playgroud)

如果我故意拼错并宣布第二个功能

zipWith' :: (a -> b -> c) -> [a] -> [b] -> [c]  
zipWith' _ [] _ = []  
zipWith' _ _ [] = []  
zipWith' f (x:xs) (y:ys) = f xs y : zipWith' f xs ys 
Run Code Online (Sandbox Code Playgroud)

然后第一个和第二个函数在编译期间抛出错误 - 至少这就是我认为正在发生的事情.

对不起提前代码转储.

它抛出了这个以前看不见的关于柱面函数的错误消息,我没有改变

Prelude> :l functions2.hs
[1 of 1] Compiling Main             ( functions2.hs, interpreted )

functions2.hs:4:26:
    Could not deduce (Integral b0) arising from a use of ‘^’
    from the context (RealFloat a)
      bound by the type signature for
                 cylinder :: RealFloat a => a -> a -> a
      at functions2.hs:1:13-40
    The type variable ‘b0’ is ambiguous
    Note: there are several potential instances:
      instance Integral Int -- Defined in ‘GHC.Real’
      instance Integral Integer -- Defined in ‘GHC.Real’
      instance Integral GHC.Types.Word -- Defined in ‘GHC.Real’
    In the second argument of ‘(*)’, namely ‘r ^ 2’
    In the expression: pi * r ^ 2
    In an equation for ‘topArea’: topArea = pi * r ^ 2

functions2.hs:4:27:
    Could not deduce (Num b0) arising from the literal ‘2’
    from the context (RealFloat a)
      bound by the type signature for
                 cylinder :: RealFloat a => a -> a -> a
      at functions2.hs:1:13-40
    The type variable ‘b0’ is ambiguous
    Note: there are several potential instances:
      instance Num Double -- Defined in ‘GHC.Float’
      instance Num Float -- Defined in ‘GHC.Float’
      instance Integral a => Num (GHC.Real.Ratio a)
        -- Defined in ‘GHC.Real’
      ...plus three others
    In the second argument of ‘(^)’, namely ‘2’
    In the second argument of ‘(*)’, namely ‘r ^ 2’
    In the expression: pi * r ^ 2
Run Code Online (Sandbox Code Playgroud)

以及关于第二个函数中的拼写错误的这个更合理的错误消息

functions2.hs:12:30:
    Couldn't match expected type ‘a’ with actual type ‘[a]’
      ‘a’ is a rigid type variable bound by
          the type signature for
            zipWith' :: (a -> b -> c) -> [a] -> [b] -> [c]
          at functions2.hs:9:13
    Relevant bindings include
      xs :: [a] (bound at functions2.hs:12:15)
      x :: a (bound at functions2.hs:12:13)
      f :: a -> b -> c (bound at functions2.hs:12:10)
      zipWith' :: (a -> b -> c) -> [a] -> [b] -> [c]
        (bound at functions2.hs:10:1)
    In the first argument of ‘f’, namely ‘xs’
    In the first argument of ‘(:)’, namely ‘f xs y’
Failed, modules loaded: none. 
Run Code Online (Sandbox Code Playgroud)

为什么?这是一个常见的错误吗?我是否破坏了第二个东西?请指教.

Ørj*_*sen 3

这是GHC 错误单#9033,于 2014 年 4 月报告并很快得到修复。

基本上,每当文件包含几乎任何类型错误时,GHC 都会跳过类型类默认步骤,这可能导致文件的其他部分给出虚假的不明确类型错误。

正如 @leftaroundabout 所指出的,^运算符是这种情况的频繁触发因素,因为它的第二个参数类型与其他类型没有连接,因此经常需要默认。

票证中列出的 GHC 版本是 7.8.2,7.8.3 于 2104 年 7 月发布,因此我假设版本 7.8.3 及更高版本已修复。