所以我正在学习如何在 Haskell 中编程。
我想看到的一件事是通过使用 map 和使用不使用列表理解的递归并且不使用 map 或任何其他高阶库函数,将 1 添加到列表的每个元素。
我认为看到这两种实现方式会很酷。
如果您了解什么map
,那么我认为编写您打算做的事情并不难。当你看到类型map
*Main> :t map
map :: (a -> b) -> [a] -> [b]
所以它需要一个函数和一个列表,并在将该函数应用于列表的每个元素后返回另一个列表。因此,为了您的预期目的,为每个元素添加一个,您可以选择要使用的功能(+1)
。所以
*Main> map (+1) [3,4,5,1,2]
[4,5,6,2,3]
如果您了解基本的haskell,现在定义自己的函数很容易。您可以查看来源map
寻求帮助。
map _ [] = []
map f (x:xs) = f x : map f xs
它为您提供实现递归递增函数所需的所有帮助,例如
add' [] = []
add' (x:xs) = (x+1) : add' xs
现在在 ghci 中试试这个
*Main> add' [3,4,5,1,2]
[4,5,6,2,3]
Satvik 很好地解释了递归版本,但列表理解版本中有一些非常有趣的东西。让我们来看看。
add1 xs = [x + 1 | x <- xs]
列表推导的语法与 Python 非常相似,但它们实际上只是普通语言结构的语法糖——do
符号!
add1 xs = do x <- xs
return (x + 1)
由于我们只是在列表 monad 上进行操作,因此我们可以对do
符号进行脱糖
add1 xs = xs >>= \x -> return (x + 1)
然后应用一些转换
add1 xs = xs >>= return . (+1)
= liftM (+1) xs
= fmap (+1) xs
= map (+1) xs
我们又回到了开始的地方。