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.
For example, I have a list [1,2,2,4,1]
and want to write a function to change every 2
to a 3
. How would I go about doing this? In Java, I know I would write the following
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?
There's not a single replacement for a for
loop in Haskell. The replacement depends on exactly what you want to do. In this case, a map
would be appropriate:
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.).
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.
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. 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).
The above pattern is quite common, so there is another function in the core libraries that can do this, and is called 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. There are many haskell functions built on top of it like map, fold, etc.
I would suggest you use one of the several resources online to get more familiar with Haskell constructs. 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 (\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:
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
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.