Haskell函数组成问题

时间:2010-03-02 12:21:49

标签: haskell

如果有效:

Prelude Data.Char> map toUpper ("sdfsd" ++ "dfgfdg")
"SDFSDDFGFDG"

那为什么不这样呢?

Prelude Data.Char> map toUpper . (++) "sdfsd" "dfgfdg"

<interactive>:1:14:
    Couldn't match expected type `a -> [Char]'
           against inferred type `[Char]'
    In the second argument of `(.)', namely `(++) "sdfsd" "dfgfdg"'
    In the expression: map toUpper . (++) "sdfsd" "dfgfdg"
    In the definition of `it': it = map toUpper . (++) "sdfsd" "dfgfdg"

2 个答案:

答案 0 :(得分:13)

map toUpper . (++) "sdfsd" "dfgfdg"

被解析为:

(map toUpper) . ((++) "sdfsd" "dfgfdg")

所以基本上你正在做

(map toUpper) . "sdfsddfgfdg"

这不起作用,因为.的第二个参数需要是一个函数,而不是一个字符串。

我认为你试图做更像(map toUpper . (++)) "sdfsd" "dfgfdg"的事情。这也不起作用,因为++的返回类型为[a] -> [a],而map toUpper的参数类型为[a]

这里的事情是,虽然有人可能认为++是一个带有两个列表并返回一个列表的函数,但它实际上是一个函数,它接受一个列表,然后返回一个函数,该函数接受另一个列表并返回一个列表。为了得到你想要的东西,你需要++进入一个带有两个列表元组并返回一个列表的函数。那被称为uncurrying。以下作品:

map toUpper . (uncurry (++)) $ ("sdfsd", "dfgfdg")

答案 1 :(得分:7)

您希望$代替.map toUpper $ (++) "sdfsd" "dfg"可以正常工作并做您想做的事情。原因是$是一个非常低优先级的函数应用程序,因此更正后的版本读作:“将函数map toUpper应用于(++) "sdfsd" "dfg"”的结果。