所以我正在学习如何在Haskell中编程。
我希望看到的一件事是通过使用map并使用不使用列表推导而不使用map或任何其他高阶库函数的递归,为列表的每个元素添加1。
我认为看到两种实施方式都很酷。
答案 0 :(得分:8)
如果您了解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]
答案 1 :(得分: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
我们回到了我们开始的地方。