如何在Haskell中编写for循环?

问题描述 投票:0回答:5

我对 Haskell 很陌生,而且对如何实现 for 循环也很困惑,因为我知道我们需要对它们使用递归。

例如,我有一个列表

[1,2,2,4,1]
,想要编写一个函数将每个
2
更改为
3
。我该怎么做呢?在Java中,我知道我会写以下内容

public void replace_two(List<Integer> ints) {
        int i = 0;
        for (int x: ints) {
            if (x == 2) {
                ints.set(i, 3);
            }
            i++;
        }
        System.out.println(ints);
    }

但我不确定如何用 Haskell 重现类似的东西?

list haskell functional-programming
5个回答
12
投票

Haskell 中没有一个可以替代

for
循环的方法。更换具体取决于您想要做什么。在这种情况下,合适的是
map

replace_two = map go
  where
    go 2 = 3
    go x = x

它的工作原理如下:

Prelude> replace_two [1,2,2,4,1]
[1,3,3,4,1]
Prelude>

4
投票

Haskell 使用不同方法的组合来“排序”数据循环,例如列表。

有帮助的两件重要事情是:

  1. 轻松声明函数并传递它,类似于我们在 oops 语言中对变量所做的事情
  2. 广泛的模式匹配

例如,我在 haskell 中声明一个函数,如果输入为 3,则返回 2,否则返回输入。

return2 x = if x == 3 then 2 else x

现在我们想将此函数应用于列表的每个元素。所以我们将使用模式匹配。

apply (x:xs) = return2 x : apply xs
apply [] = []

这里模式

x:xs
将打破列表并获取
x
中的第一个元素,而
xs
将拥有列表的其余部分。在函数内部,您可以看到我们递归地应用了它。

我没有在IDE中检查上面的代码,所以它可能有语法错误,还有其他你需要验证的东西(列表末尾,在上面的代码中该函数会导致异常)。

上面的模式很常见,所以核心库中有另一个函数可以做到这一点,叫做map。所以你可以这样做:

map return2 [your list]

正如我所说,在 haskell 中,有很多方法可以本质上循环遍历事物,但从根本上讲,它们分解为将函数应用于数据结构中的各个项目。在它之上构建了许多 haskell 函数,例如 map、fold 等。

我建议您使用在线资源之一来更加熟悉 Haskell 结构。我喜欢并且很容易理解的一个是 Learn you a Haskell


2
投票

map
匿名函数一起使用:

λ> map (\x -> if x==2 then 3 else x) [1,2,2,4,1]
[1,3,3,4,1]

1
投票

使用模式和递归的另一种基本方法。

replace :: [Int] -> [Int]
replace [] = [] -- base case
replace (2:x)  = 3:replace(x) --if 2 then replace by 3
replace (y:x) = y:replace(x) -- do nothing

-1
投票

除了

map
,也许你可以使用
forM
中的
Control.Monad
来模仿其他命令式语言中的
for
循环:

import Control.Monad
arr = [1, 2, 2, 4, 1]
forM arr $ \i ->
    if i == 2 then return 3 else return i

但是,您需要了解什么是

Monad

© www.soinside.com 2019 - 2024. All rights reserved.