[英]How to write a for loop in Haskell?
I am really new to Haskell and also really confused about how to implement for loops since I know we need to use recursion for them. 我真的对Haskell并不陌生,也对如何实现for循环感到困惑,因为我知道我们需要对它们使用递归。
For example, I have a list [1,2,2,4,1]
and want to write a function to change every 2
to a 3
. 例如,我有一个列表
[1,2,2,4,1]
并想编写一个函数,将每2
更改为3
。 How would I go about doing this? 我将如何去做呢? In Java, I know I would write the following
在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);
}
but I am not sure how I could reproduce something else like this with Haskell? 但是我不确定如何用Haskell重现其他类似内容?
There's not a single replacement for a for
loop in Haskell. Haskell中没有一个
for
循环的替代品。 The replacement depends on exactly what you want to do. 替换取决于您要执行的操作。 In this case, a
map
would be appropriate: 在这种情况下,
map
将是合适的:
replace_two = map go
where
go 2 = 3
go x = x
And it works like this: 它是这样的:
Prelude> replace_two [1,2,2,4,1]
[1,3,3,4,1]
Prelude>
Haskell uses a combination of different ways to 'sort of' loop over data (list, etc.). Haskell使用多种不同方式的组合来对数据(列表等)进行“排序”循环。
The two important things helping this is: 帮助此的两个重要事项是:
So for example I declare a function in haskell to return 2 if input is 3 else return input. 因此,例如,我在haskell中声明了一个函数,如果输入为3,则返回2,否则返回输入。
return2 x = if x == 3 then 2 else x
Now we want to apply this function to every element of the list. 现在,我们想将此功能应用于列表的每个元素。 So we will use pattern matching
所以我们将使用模式匹配
apply (x:xs) = return2 x : apply xs
apply [] = []
Here the pattern x:xs
will break the list and take the first element in x
while xs
will have the remainder of the list. 在这里,模式
x:xs
将中断列表并占据x
的第一个元素,而xs
将拥有列表的其余部分。 Inside the function you can see we have applied it recursively. 在函数内部,您可以看到我们已递归应用它。
I have not checked the above code in IDE so might have syntax errors, also there are other things you will want to validate (end of list, in above code the function would cause exception). 我没有在IDE中检查以上代码,因此可能存在语法错误,还有其他您需要验证的内容(列表结尾,在上述代码中,该函数将导致异常)。
The above pattern is quite common, so there is another function in the core libraries that can do this, and is called map. 上面的模式很常见,因此核心库中还有另一个函数可以执行此操作,称为map。 So you could have done:
因此,您可以完成以下操作:
map return2 [your list]
As I said in haskell there are many ways to essentially loop over things, but at the base they break down to applying the function to individual items in the data structure. 就像我在haskell中所说的那样,有很多方法可以使事物本质上循环,但是从根本上讲,它们分解为将函数应用于数据结构中的各个项目。 There are many haskell functions built on top of it like map, fold, etc.
在其之上构建了许多haskell函数,例如地图,折叠等。
I would suggest you use one of the several resources online to get more familiar with Haskell constructs. 我建议您使用几种在线资源之一来更熟悉Haskell构造。 One that I liked and easy to follow is Learn you a hakell
我喜欢并且易于理解的一个是了解您
Another basic approach using patterns and recursion. 另一种使用模式和递归的基本方法。
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
Using map
with an anonymous function: 使用具有匿名功能的
map
:
λ> map (\x -> if x==2 then 3 else x) [1,2,2,4,1]
[1,3,3,4,1]
Except map
, maybe you can use forM
from Control.Monad
to mimic the for
loop in other imperative languages: 除了
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
However, you need to understand what is Monad
. 但是,您需要了解什么是
Monad
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.