如何在Haskell中编写for循环?

pu3pd22g  于 2022-11-14  发布在  其他
关注(0)|答案(5)|浏览(173)

我对Haskell真的很陌生,也对如何实现for循环真的很困惑,因为我知道我们需要对它们使用递归。
例如,我有一个列表[1,2,2,4,1],我想写一个函数把每个2都变成一个3

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 复制其他类似的东西?

7tofc5zh

7tofc5zh1#

在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>
brvekthn

brvekthn2#

Haskell使用不同方法的组合来对数据进行“排序”循环,例如列表。
两件重要的事情有助于这一点:
1.易于声明函数并传递它,类似于我们在oops语言中对变量所做的操作
1.广泛的模式匹配
例如,我在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结构。

2izufjch

2izufjch3#

map与匿名函数一起使用:

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

k4ymrczo4#

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

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
bis0qfac

bis0qfac5#

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

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

但是,您需要了解什么是Monad

相关问题