为什么 Haskell 函数声明中的拼写错误会导致 GHCi 在之前编译的代码周围抛出错误?
Why does a typo in a Haskell function declaration cause GHCi to throw errors around previously compiling code?
这是一个奇怪的问题。通过 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
这在 GHCi 中编译
zipWith' :: (a -> b -> c) -> [a] -> [b] -> [c]
zipWith' _ [] _ = []
zipWith' _ _ [] = []
zipWith' f (x:xs) (y:ys) = f x y : zipWith' f xs ys
如果我故意打错字然后把第二个函数声明成这样
zipWith' :: (a -> b -> c) -> [a] -> [b] -> [c]
zipWith' _ [] _ = []
zipWith' _ _ [] = []
zipWith' f (x:xs) (y:ys) = f xs y : zipWith' f xs ys
然后第一个和第二个函数在编译期间抛出错误 - 至少我认为是这样。
对于代码转储提前抱歉。
它抛出这个我没有更改的关于圆柱函数的以前看不见的错误消息
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
以及关于第二个函数中拼写错误的更合理的错误消息
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.
为什么?这是一个常见的错误吗?我是否通过破坏第二个来破坏第一个?请指教
这是 GHC bug ticket #9033,于 2014 年 4 月报告并迅速修复。
基本上,每当文件包含几乎 any 类型错误时,GHC 将跳过类型 class 默认步骤,这可能导致文件的其他部分给出虚假的不明确的类型错误。
正如@leftaroundabout 指出的那样,^
运算符是这种情况的常见触发器,因为它的第二个参数类型与其他类型无关,因此经常需要默认。
工单中列出的 GHC 版本是 7.8.2,而 7.8.3 是在 2104 年 7 月发布的,所以我假设版本是 7.8.3 及更高版本。
这是一个奇怪的问题。通过 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
这在 GHCi 中编译
zipWith' :: (a -> b -> c) -> [a] -> [b] -> [c]
zipWith' _ [] _ = []
zipWith' _ _ [] = []
zipWith' f (x:xs) (y:ys) = f x y : zipWith' f xs ys
如果我故意打错字然后把第二个函数声明成这样
zipWith' :: (a -> b -> c) -> [a] -> [b] -> [c]
zipWith' _ [] _ = []
zipWith' _ _ [] = []
zipWith' f (x:xs) (y:ys) = f xs y : zipWith' f xs ys
然后第一个和第二个函数在编译期间抛出错误 - 至少我认为是这样。
对于代码转储提前抱歉。
它抛出这个我没有更改的关于圆柱函数的以前看不见的错误消息
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
以及关于第二个函数中拼写错误的更合理的错误消息
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.
为什么?这是一个常见的错误吗?我是否通过破坏第二个来破坏第一个?请指教
这是 GHC bug ticket #9033,于 2014 年 4 月报告并迅速修复。
基本上,每当文件包含几乎 any 类型错误时,GHC 将跳过类型 class 默认步骤,这可能导致文件的其他部分给出虚假的不明确的类型错误。
正如@leftaroundabout 指出的那样,^
运算符是这种情况的常见触发器,因为它的第二个参数类型与其他类型无关,因此经常需要默认。
工单中列出的 GHC 版本是 7.8.2,而 7.8.3 是在 2104 年 7 月发布的,所以我假设版本是 7.8.3 及更高版本。