即使缺少参数,此功能为何仍起作用? [英] Why does this function work even though the argument is missing?
问题描述
我正在尝试理解以下代码:
I'm trying to understand the following piece of code:
import Data.Char (ord)
encodeInteger :: String -> Integer
encodeInteger = read . concatMap ch
where ch c = show (ord c)
但是当将 encodeInteger
定义为需要一个字符串的函数时,我看不到它如何工作,但是在第二行中,该函数是在没有该字符串参数的情况下实现的.
But I don't see how this can work when encodeInteger
is defined as a function that takes a string, but in the second line, the function is implemented without that string argument.
此外, concatMap
(根据hoogle)具有一个功能和一个列表,但仅提供了功能 ch
.
Also, concatMap
(according to hoogle), takes a function and a list, but only the function ch
is provided.
为什么此代码仍然有效?该论点以某种方式神奇地通过了吗?与欺骗有关吗?
Why does this code still work? Is the argument somehow magically passed? Has it something to do with currying?
为什么不能这样更改它?
edit: And why doesn't it work to change it like this:
encodeInteger :: String -> Integer
encodeInteger a = read . concatMap ch a
where ch c = show (ord c)
推荐答案
基本定义一个函数
f = g
与定义函数相同
f x = g x
在特定情况下,您可以使用
In your specific case, you can use
encodeInteger a = (read . concatMap ch) a
定义您的功能.括号是必需的,否则解析为
to define your function. The parentheses are needed, otherwise it is parsed as
encodeInteger a = (read) . (concatMap ch a)
和 concatMap ch
不是函数,不能组成.最多你可以写
and concatMap ch a
is not a function and can not be composed. At most you could write
encodeInteger a = read (concatMap ch a)
-- or
encodeInteger a = read $ concatMap ch a
关于为什么 concatMap ch
仅接受一个参数?".这是部分应用程序,在Haskell中非常常见.如果有
About "why concatMap ch
takes only one argument?". This is a partial application, which is very common in Haskell. If you have
f x y z = x+y+z
您可以使用更少的参数调用 f
,并获得其余参数的函数结果.例如, f 1 2
是采用 z
并返回 1 + 2 + z
的函数.
you can call f
with fewer arguments, and obtain as the result a function of the remaining arguments. E.g., f 1 2
is the function taking z
and returning 1+2+z
.
具体来说,感谢Currying,没有一个函数接受两个或更多参数.每个函数始终只接受一个参数.当您拥有类似
Concretely, thanks to Currying, there's no such a thing as a function taking two or more arguments. Every function always takes only one argument. When you have a function like
foo :: Int -> Bool -> String
然后 foo
接受一个参数,即 Int
.它返回一个函数,该函数需要一个 Bool
,最后返回一个 String
.您可以通过编写文字来可视化
then foo
takes one argument, an Int
. It returns a function, which takes a Bool
and finally returns a String
. You can visualize this by writing
foo :: Int -> (Bool -> String)
无论如何,如果您查找currying和部分应用程序,则会发现很多示例.
Anyway, if you look up currying and partial application, you will find plenty of examples.
这篇关于即使缺少参数,此功能为何仍起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!