在 ghci 中,:t
命令在诸如 3 4
、(sin . (+)) 1 2 3 4 这样的表达式中没有发现任何错误
, 罪过。 (+) 1 2 3 4
或 (-) - (-)
并愉快地为它们提供类型信息:
3 4 :: (Num (a -> t), Num a) => t
sin . (+) 1 2 3 4
:: (Floating c, Num (a1 -> a2 -> a -> c), Num a1, Num a2) => a -> c
(sin . (+)) 1 2 3 4
:: (Floating ((a -> a1 -> t) -> a -> a1 -> t), Num (a -> a1 -> t),
Num a, Num a1) =>
t
(-) - (-) :: (Num (a -> a -> a), Num a) => a -> a -> a
我相信这背后是有原因的。但我很难想象 (3 4)
有意义的上下文(我不是指实用的东西,而是至少可以编译的东西),如果有人给我线索,我将不胜感激。
最佳答案
很多东西都带有疯狂或不可能的推断约束“类型检查”。我们有 map::(a -> b) -> [a] -> [b]
而不仅仅是严格更通用的 fmap::Functor f => ( a -> b) -> f a -> f b
是如果你不正确地使用后者,你很可能会得到一个错误 No instance (Functor [something obviously not a functor])
而不是更友好的 Expecting [a], got ...
。
Num
/Floating
的情况尤其令人不安,因为所有数字文字都使用类型类进行了重载。编译器会愉快地为任何整数文字推断出几乎任何类型,如果可能的话,只需将其作为约束。通常这最终会导致实例解析错误。
此外,可以编写一个并非完全无意义的instance Num b => Num (a -> b)
。 That's a different question, though.正如我在那里指出的那样,我觉得这是一个有问题的想法,而且它有意不在 base
中。 (或者,就此而言,我查看的替代数字类型类包。)
关于haskell - Haskell 中的 Floating (a -> a), Num (a -> a -> a) 等,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26696105/