[英]How to write a for loop in Haskell?
我真的对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重现其他类似内容?
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>
Haskell使用多种不同方式的组合来对数据(列表等)进行“排序”循环。
帮助此的两个重要事项是:
因此,例如,我在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函数,例如地图,折叠等。
另一种使用模式和递归的基本方法。
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
使用具有匿名功能的map
:
λ> map (\x -> if x==2 then 3 else x) [1,2,2,4,1]
[1,3,3,4,1]
除了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
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.