我有一个例如:
firstTop40 :: Maybe Int
firstTop40 = find (\x -> digitSum x == 40) [1..]
我的问题是为什么我在函数原型中需要“可能”?
第二个问题是:为什么我需要\x
?
答案 0 :(得分:2)
你需要Maybe
,因为你不确定你是否会找到你想要的东西,这是Haskell的说法:“也许你得到的结果,也许不是”< / em>的
所以说你有这个:
find (\x -> x > 40) [1 .. 10]
它会查找第一个大于40的数字,在一个只有10的列表中。它会找到什么?什么都没有。
这正是它所发现的:
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
然后你可能会说“好吧,如果找不到任何东西它为什么不返回0?”,那是因为,如果0是你搜索的可能结果之一怎么办? ,你想要它既意味着“我发现0”而“我什么都没发现”?当然不是!这就是为什么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
您可以将其视为“在1到10的列表中找到大于或等于5的任何内容”,然后生成Just 5
以上示例是可行的,因为您可以在互联网上阅读更多有关currying
和/或partial application
的内容。
答案 1 :(得分:0)
您需要maybe
,因为find
会返回Maybe
。如果它找到一个值,比如10,则返回Just 10
,否则返回Nothing
。
\x -> digitSum x== 40
是lambda表达式,\x
是绑定变量的方式。