I am trying to write the map function using foldr. The problem is that when I ran this code :
> myMap f xs = foldr (\ acc x -> acc :(f x)) [] xs
I have the following problem:
No instance for (Num [a0]) arising from a use of 'it'
but when I run
myMap f xs = foldr (\x acc-> (f x):acc) [] xs
It works perfectly. Any ideas why?
The error you posted is not coming from your definition of myMap
, it's coming from how you're using it. The type of the first myMap
is ([a] -> [a]) -> [a] -> [a]
, which does not match the type of Prelude.map
. In the second one you've swapped your variable names and also which one you're applying f
to. The compiler doesn't care what you name the arguments in your lambda being passed to foldr
, so foldr (\\x acc -> fx : acc)
is identical to foldr (\\foo bar -> f foo : bar)
. That may be what's tripping you up here.
The second one works because (to put it simply) it's correct. In the first you're applying f
to your accumulator list x
(even though you have a variable named acc
it's not your accumulator), so f
must take a list and return a list. In the second you're applying f
to each element, then prepending that to your accumulator list. If you had myMap (+1)
, it would have the type
myMap (+1) :: Num [a] => [a] -> [a]
Which says that you must pass it a list of values [a]
where [a]
implements Num
, and currently there is no instance for Num [a]
, nor will there ever be.
TL;DR: In the first one you're applying your mapped function to your accumulator list, in the second one you're applying the mapped function to each element.
the type of foldr is
foldr :: (a -> b -> b) -> b -> [a] -> b
therefore the binary operation that foldr uses to traverse and accumulate the list has type (a -> b -> b)
,it first take an element of the list (type a
)then the accumulator (type b
) resulting in an expression of type b.
So, your first myMap function does not work becuase you are using "acc" and "x" in reverse order. You want to apply f
to x then append it to the acummulator of type b
( a list in this case)
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.