Writing a custom map function

2019-07-18 13:41发布

Now there might be something in the Haskell Libraries to do what I want. I'm enough of a noob to not know any better and I'm trying to write a custom map function using the tools that I know. The type signature needs to be

myMap :: (Monad m) => (a -> b) -> [m a] -> [m b]

where myMap f as returns a list after applying f to each of the value in each Monad in as.

My first attempt was

myMap f = map (\x x >>= f)

However, this has a type signature of

myMap :: (Monad m) => (a -> m b) -> [m a] -> [m b]

This is so close to what I need, I can scream. Now I need some tips of how to continue from here. I really hope it is as easy as a library function, but I'm willing to write my own short function to do this instead.

Related Question:

Mapping a function over two input lists

2条回答
太酷不给撩
2楼-- · 2019-07-18 14:08

If you could turn your (a -> b) function in to m a -> m b then you could use map itself. So, what do you need to do this? Hoogle is quite good for this sort of thing. Doing a search for (a -> b) -> (m a -> m b) gives these results:

http://www.haskell.org/hoogle/?hoogle=%28a+-%3E+b%29+-%3E+%28m+a+-%3E+m+b%29

Near the top are fmap (which use Functor) and liftM (which use Monad). Either would do, but you're using monads, so let's go with liftM. Thus:

myMap :: Monad m => (a -> b) -> [m a] -> [m b]
myMap f = map (liftM f)
查看更多
Emotional °昔
3楼-- · 2019-07-18 14:11

You were almost there in your attempt, what you were missing was return:

myMap :: (Monad m) => (a -> b) -> [m a] -> [m b]
myMap f = map $ flip (>>=) $ return . f

Basically you needed a way to

  • unwrap a from m a - we use >>= for that
  • apply f to it
  • wrap f return value in m to get m b - we use return for that
查看更多
登录 后发表回答