質問

I found a solution to my exercise on the internet but I'm not sure what is it. The result is correct though.

foldr (\n acc -> (n*10):acc) []

Could someone explain me exactly the steps of that function please? This should multiply all the elements of the list by 10.

Thank you

役に立ちましたか?

解決

The foldr function can be defined as following:

foldr :: (a -> b -> b) -> b -> [a] -> b
foldr f z []     = z
foldr f z (x:xs) = f x (foldr f z xs)

It takes a list of values of type a and a single value of type b – the accumulator. It takes items from the list, combines them with the accumulator and returns the final value. In your case, a is some number and b is in fact also a list of numbers. The complete type of your function is Num a => [a] -> [a].

Consider application of your function to a list [1,2,3]:

foldr (\n acc -> (n*10):acc) [] [1,2,3] ~~>
(\n acc -> (n*10):acc) 1 (foldr (\n acc -> (n*10):acc) [] [2,3]) ~~>
(1*10) : foldr (\n acc -> (n*10):acc) [] [2,3] ~~>
10 : foldr (\n acc -> (n*10):acc) [] [2,3] ~~>
10 : (\n acc -> (n*10):acc) 2 (foldr (\n acc -> (n*10):acc) [] [3]) ~~>
10 : (2*10) : foldr (\n acc -> (n*10):acc) [] [3]
10 : 20 : foldr (\n acc -> (n*10):acc) [] [3] ~~>
10 : 20 : (\n acc -> (n*10):acc) 3 (foldr (\n acc -> (n*10):acc) [] []) ~~>
10 : 20 : (3*10) : foldr (\n acc -> (n*10):acc) [] [] ~~>
10 : 20 : 30 : foldr (\n acc -> (n*10):acc) [] [] ~~>
10 : 20 : 30 : []

他のヒント

If you're not allowed to use map because this is homework, then you're probably not allowed to use foldr either. And using foldr to multiply every element in a list by 10 would be a rather silly way to do it (except as a learning exercise). As a general rule:

  • If you want to do something to every element in a list, and get a list as the result, then you probably want some sort of map function.
  • If you want to do something to every element in a list, and get a single value as the result, then you probably want one of the fold functions.

So let's write our own function. The function will take a list of numbers, and return a list. If you want to work with Ints, then:

myFunction :: [Int] -> [Int]

(Better yet, instead of hard-coding in 10, you could let that be an input parameter. I'll leave that as an exercise for you.)

We could use recursion to implement this function. When using recursion, start by asking yourself "what is the base (simplest) case". Well, that would be an empty list. If we get a list, there's nothing to do, so we just return the empty list.

myFunction [] = []

Now, what if our list is non-empty? Well, we can multiply the first element by 10, and concatenate that with the result of running myFunction on the rest of the list.

myFunction (x:xs) = x*10 : myFunction xs
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top