2016-07-15 125 views
2

我有这两个表达式:

  1. foldr (-) 0 . map (uncurry (*)) $ coords 5 7

  2. 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) 

任何人都可以告诉我这两者有什么区别?谢谢。

回答

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 
+0

我现在看到,谢谢,我想知道为什么(uncurry(*)))作为参数与()不会导致问题,但最后一个参数(坐标5 7)呢?和顺便说一句,如果表达式中有多个$?口译员会如何解释这个表达? – linjunshi

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) 
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的功能 - 在你的情况下,这是foldr (-) 0 . map (uncurry (*)) - 在RHS表达coords 5 7。将函数应用于其参数当然也正是如果您只写了function (argument),但是您需要指定正确的函数!要编写例如没有$,你必须组作为

(foldr (-) 0 . map (uncurry (*))) (coords 5 7) 

,而你尝试不同的分析:功能应用结合更加紧密地比任何缀,甚至.,所以你的努力就等于

foldr (-) 0 . (map (uncurry (*)) (coords 5 7)) 

这是没有道理的。

相关问题