Haskell 为什么即使缺少参数,该函数仍能工作?

Haskell 为什么即使缺少参数,该函数仍能工作?,haskell,Haskell,我试图理解以下代码: import Data.Char (ord) encodeInteger :: String -> Integer encodeInteger = read . concatMap ch where ch c = show (ord c) 但是当encodeInteger被定义为一个接受字符串的函数时,我看不出这是如何工作的,但是在第二行中,函数是在没有字符串参数的情况下实现的 另外,concatMap(根据胡格尔的说法)接受一个函数和一个列表,但只提供函

我试图理解以下代码:

import Data.Char (ord)

encodeInteger :: String -> Integer
encodeInteger = read . concatMap ch
    where ch c = show (ord c)
但是当
encodeInteger
被定义为一个接受字符串的函数时,我看不出这是如何工作的,但是在第二行中,函数是在没有字符串参数的情况下实现的

另外,
concatMap
(根据胡格尔的说法)接受一个函数和一个列表,但只提供函数
ch

为什么这个代码仍然有效?这场争论是否神奇地通过了?这和咖喱有关吗

编辑:为什么这样更改它不起作用:

encodeInteger :: String -> Integer
encodeInteger a = read . concatMap ch a
    where ch c = show (ord c)

基本上定义了一个函数

f = g
与定义函数相同

f x = g x
在您的特定情况下,您可以使用

encodeInteger a = (read . concatMap ch) a
来定义你的函数。括号是必需的,否则它将被解析为

encodeInteger a = (read) . (concatMap ch a)
concatMap ch a
不是一个函数,不能组合。你最多只能写

encodeInteger a = read (concatMap ch a)
-- or
encodeInteger a = read $ concatMap ch a
关于“为什么
concatMap ch
只接受一个参数?”。这是一个局部应用程序,在Haskell中非常常见。如果你有

f x y z = x+y+z
您可以使用较少的参数调用
f
,并获得剩余参数的函数作为结果。例如,
F12
是一个接受
z
并返回
1+2+z
的函数

具体地说,多亏了Curry,没有一个函数包含两个或多个参数。每个函数总是只接受一个参数。当你有一个函数,比如

foo :: Int -> Bool -> String
然后
foo
接受一个参数,一个
Int
。它返回一个函数,该函数接受一个
Bool
,最后返回一个
字符串。你可以通过写作来想象这一点

foo :: Int -> (Bool -> String)
无论如何,如果你查找curry和partialapplication,你会发现很多例子

encodeInteger :: String -> Integer
encodeInteger = read.concatMap (\char -> show $ ord char)
“=”左侧(LHS)的
encodeInteger
是一个名称;指“=”右侧(RHS)的功能。两者都有函数类型:
String->Integer
。两者都接受字符列表并生成一个整数。Haskell使我们能够在不指定形式参数的情况下表达这样的函数等式(一种称为

现在,让我们看看RHS。(.)运算符将两个函数组合在一起。组合函数从
concatMap
获取一个字符串作为其输入,并从
read
生成一个整数作为组合函数的输出


concatMap
本身接受2个输入,但我们需要为组合函数省略第二个输入,它需要一个字符串作为输入。我们通过部分应用
concatMap
,只包括它的第一个参数来实现这一点。

在Haskell中,函数
A->b->c
意味着函数
A->(b->c)
,即如果应用于
A
,它会产生一个
b->c
fab
同样只是
(fa)b
。因此,由于
concatMap
是(简化的)
(a->[b])->[a]->[b]
concatMap ch
是一个函数
[a]->[b]
。嗨,谢谢,这一切都有意义。但是我不能做我在编辑下添加的吗?@user66875您需要将整个合成应用于参数。现在,它期望
concatMap ch a
是一个函数(
的第二个参数)。使用
read。concatMap ch$a
为什么需要将参数放在该位置?