我有这两个表达式:
foldr (-) 0 . map (uncurry (*)) $ coords 5 7
foldr (-) 0 . map (uncurry (*)) (coords 5 7)
(1)工程打印出结果,但(2)有错误说:
<interactive>:50:15:
Couldn't match expected type ‘a -> t0 c’
with actual type ‘[Integer]’
Relevant bindings include
it :: a -> c (bound at <interactive>:50:1)
Possible cause: ‘map’ is applied to too many arguments
In the second argument of ‘(.)’, namely
‘map (uncurry (*)) (coords 5 7)’
In the expression: foldr (-) 0 . map (uncurry (*)) (coords 5 7)
任何人都可以告诉我这两者之间的区别是什么吗?感谢。
答案 0 :(得分:3)
foldr (-) 0 . map (uncurry (*)) $ coords 5 7
-- is equivalent to
( foldr (-) 0 . map (uncurry (*)) ) (coords 5 7)
-- and to
foldr (-) 0 ( map (uncurry (*)) (coords 5 7) )
foldr (-) 0 . map (uncurry (*)) (coords 5 7)
-- is equivalent to
foldr (-) 0 . ( map (uncurry (*)) (coords 5 7) )
-- and to
\x -> foldr (-) 0 ( map (uncurry (*)) (coords 5 7) x)
在后者中,map (uncurry (*)) (coords 5 7)
的结果作为第二个参数传递给.
,但它是一个列表,而不是函数,因此会出现类型错误。
注意也可以:
foldr (-) 0 $ map (uncurry (*)) (coords 5 7)
答案 1 :(得分:3)
这是一个更简单的例子:
Prelude> id . id $ "Example"
"Example"
Prelude> id . id ("Example")
<interactive>:2:10:
Couldn't match expected type ‘a -> c’ with actual type ‘[Char]’
Relevant bindings include it :: a -> c (bound at <interactive>:2:1)
In the first argument of ‘id’, namely ‘("Example")’
In the second argument of ‘(.)’, namely ‘id ("Example")’
In the expression: id . id ("Example")
问题是函数应用程序的绑定强于(.)
。 ($)
的固定级别修复了此问题:
id . id $ "Example" = (id . id) $ "Example"
= (id . id) "Example"
但是,对于(...)
,函数应用程序获胜,最终使用(.)
作为第二个参数使用非函数:
id . id ("Example") = id . id "Example"
= id . (id "Example") -- apply id
= id . ("Example")
= type error, since "Example" isn't a function
答案 2 :(得分:2)
$
只是一个中缀形式的无操作。因为它是一个固定性较低的中缀运算符:
GHCi> :i $
($) :: (a -> b) -> a -> b -- Defined in ‘GHC.Base’
infixr 0 $
它出现的任何表达式都被解析,好像它有括号。在您的示例中,
foldr (-) 0 . map (uncurry (*)) $ coords 5 7
被解析为
( (foldr (-) 0)
. (map (uncurry (*))) )
$ (coords 5 7)
因为$
的固定度低于.
。这与您编写1 + 2 * 3
的方式完全相同:这被解析为(1) + (2*3)
,因为*
的固定性高于+
。
当$
运算符被评估时,它所做的就是将LHS上的函数应用于RHS表达式{在你的情况下,这是foldr (-) 0 . map (uncurry (*))
{ {1}}。将函数应用于其参数当然也正是如果您刚刚编写coords 5 7
会发生什么,但是您需要指定正确的函数!要为您编写没有function (argument)
的示例,您必须将其分组为
$
而你的尝试的解析方式不同:函数应用程序比任何中缀绑定得更紧,甚至( foldr (-) 0 . map (uncurry (*)) ) (coords 5 7)
,所以你的尝试等同于
.
这没有意义。