let f = show.sum.map read.words
f "1 2"
有效。
show.sum.map read.words "1 2"
我收到错误:
<interactive>:19:19:
Couldn't match expected type ‘a -> [String]’
with actual type ‘[String]’
Relevant bindings include
it :: a -> String (bound at <interactive>:19:1)
Possible cause: ‘words’ is applied to too many arguments
In the second argument of ‘(.)’, namely ‘words "1 2"’
In the second argument of ‘(.)’, namely ‘map read . words "1 2"’
Prelude> :t show.sum.map
show.sum.map
:: (Num [b], Show b, Foldable ((->) [a])) => (a -> b) -> String
Prelude> show.sum.map read.words "1 2"
<interactive>:21:19:
Couldn't match expected type ‘a -> [String]’
with actual type ‘[String]’
Relevant bindings include
it :: a -> String (bound at <interactive>:21:1)
Possible cause: ‘words’ is applied to too many arguments
In the second argument of ‘(.)’, namely ‘words "1 2"’
In the second argument of ‘(.)’, namely ‘map read . words "1 2"’
Prelude>
我想知道为什么? (show.sum.map read.words)“1 2”也可以工作。
答案 0 :(得分:8)
问题在于应用程序比应用程序绑定得更紧密,而应用程序实际上具有任何Haskell运算符的最高优先级。这意味着您的代码实际解析
show.sum.map read.(words "1 2")
不进行类型检查,因为words "1 2"
的类型为String
,而不是.
组成的内容。为了解决这个问题,您可以使用$
运算符,该运算符专门用作应用程序,但优先级最低而不是最高优先级。
show.sum.map read.words $ "1 2"
将按预期工作,因为它具有正确的关联。这通常是为什么你会经常看到foo . bar . baz $ quux
的Haskell代码(至少是我的Haskell代码)中的模式。