也许输入 haskell,我的语句中的斜线是什么?
maybe type in haskell, and what is slash in my statement?
我有一个例子:
firstTop40 :: Maybe Int
firstTop40 = find (\x -> digitSum x == 40) [1..]
我的问题是为什么函数原型中需要"maybe"?
第二个问题是:为什么这里需要 \x
?
你需要 maybe
因为 find
returns 一个 Maybe
。如果它找到一个值,比如 10,它 returns Just 10
否则它 returns Nothing
.
\x -> digitSum x== 40
是 lambda 表达式,\x
是绑定变量的方式。
你需要 Maybe
因为你不确定是否能找到你要找的东西,这是 Haskell 的说法:"maybe you're getting a result, maybe not".
假设你有这个:
find (\x -> x > 40) [1 .. 10]
它会在一个只到 10 的列表中查找大于 40 的第一个数字。它会找到什么?没有。
这正是它找到的:
Prelude Data.List> find (\x -> x > 40) [1 .. 10]
Nothing
Nothing
是一个Maybe
的两种可能结果之一,另一个是Just
。
如果我将 > 40
更改为 >= 5
,结果将是这样的:
Prelude Data.List> find (\x -> x >= 5) [1 .. 10]
Just 5
那么你可能会说 "well, why doesn't it just return 0 if it doesn't find anything?",那是因为,如果 0 是你搜索的可能结果之一,你会希望它都表示 "I found 0" 和 "I found nothing"?当然不是!这就是为什么 Nothing
意味着你什么也没找到。
至于为什么要写\x
,也很简单
您展示的示例代码也可以这样写:
sumIs40 :: Int -> Bool
sumIs40 x = digitSum x == 40
firstTop40 :: Maybe Int
firstTop40 = find sumIs40 [1..]
但是假设您只使用了一次 sumIs40
,而且它就在您代码中的那个地方,因此您将 sumIs40
替换为 \
,并更改 =
到 ->
并将其放在通常调用函数的位置。
这叫做 anonymous
函数,或 lambda
函数,稍微谷歌一下就会告诉你更多关于它们的信息以及它们的用处,但你基本上可以想到它们作为没有名字的一次性函数。
实际上,更高级的说明:如果您愿意,可以像这样完全省略 \x ->
:
Prelude Data.List> find (>= 5) [1 .. 10]
Just 5
您可以将其读作 "find anything greater-than-or-equal-to 5, in a list from 1 to 10",然后产生 Just 5
上面的例子是可能的,因为有一个叫 currying
and/or partial application
的东西,你也可以在互联网上阅读更多关于它的信息。
我有一个例子:
firstTop40 :: Maybe Int
firstTop40 = find (\x -> digitSum x == 40) [1..]
我的问题是为什么函数原型中需要"maybe"?
第二个问题是:为什么这里需要 \x
?
你需要 maybe
因为 find
returns 一个 Maybe
。如果它找到一个值,比如 10,它 returns Just 10
否则它 returns Nothing
.
\x -> digitSum x== 40
是 lambda 表达式,\x
是绑定变量的方式。
你需要 Maybe
因为你不确定是否能找到你要找的东西,这是 Haskell 的说法:"maybe you're getting a result, maybe not".
假设你有这个:
find (\x -> x > 40) [1 .. 10]
它会在一个只到 10 的列表中查找大于 40 的第一个数字。它会找到什么?没有。
这正是它找到的:
Prelude Data.List> find (\x -> x > 40) [1 .. 10]
Nothing
Nothing
是一个Maybe
的两种可能结果之一,另一个是Just
。
如果我将 > 40
更改为 >= 5
,结果将是这样的:
Prelude Data.List> find (\x -> x >= 5) [1 .. 10]
Just 5
那么你可能会说 "well, why doesn't it just return 0 if it doesn't find anything?",那是因为,如果 0 是你搜索的可能结果之一,你会希望它都表示 "I found 0" 和 "I found nothing"?当然不是!这就是为什么 Nothing
意味着你什么也没找到。
至于为什么要写\x
,也很简单
您展示的示例代码也可以这样写:
sumIs40 :: Int -> Bool
sumIs40 x = digitSum x == 40
firstTop40 :: Maybe Int
firstTop40 = find sumIs40 [1..]
但是假设您只使用了一次 sumIs40
,而且它就在您代码中的那个地方,因此您将 sumIs40
替换为 \
,并更改 =
到 ->
并将其放在通常调用函数的位置。
这叫做 anonymous
函数,或 lambda
函数,稍微谷歌一下就会告诉你更多关于它们的信息以及它们的用处,但你基本上可以想到它们作为没有名字的一次性函数。
实际上,更高级的说明:如果您愿意,可以像这样完全省略 \x ->
:
Prelude Data.List> find (>= 5) [1 .. 10]
Just 5
您可以将其读作 "find anything greater-than-or-equal-to 5, in a list from 1 to 10",然后产生 Just 5
上面的例子是可能的,因为有一个叫 currying
and/or partial application
的东西,你也可以在互联网上阅读更多关于它的信息。