简体   繁体   中英

Haskell- write map function using foldr

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM