Writing a custom map function

最后都变了- 提交于 2019-12-11 02:49:59

问题


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


回答1:


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)



回答2:


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


来源:https://stackoverflow.com/questions/19216243/writing-a-custom-map-function

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!