-3

所以我正在学习如何在 Haskell 中编程。

我想看到的一件事是通过使用 map 和使用不使用列表理解的递归并且不使用 map 或任何其他高阶库函数,将 1 添加到列表的每个元素。

我认为看到这两种实现方式会很酷。

4

2 回答 2

9

如果您了解什么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]
于 2013-02-01T04:19:48.173 回答
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

我们又回到了开始的地方。

于 2013-02-01T23:46:35.163 回答