现在,Haskell库中可能有一些东西可以满足我的需求。我已经足够了一个菜鸟,不知道更好,我正在尝试使用我所知道的工具编写自定义地图功能。类型签名需要
myMap :: (Monad m) => (a -> b) -> [m a] -> [m b]
myMap f as
将f
应用于as
中每个Monad中的每个值后,myMap f = map (\x x >>= f)
返回一个列表。
我的第一次尝试是
myMap :: (Monad m) => (a -> m b) -> [m a] -> [m b]
但是,它的类型签名为
{{1}}
这非常接近我的需要,我可以尖叫。现在我需要一些如何从这里继续的提示。我真的希望它像库函数一样简单,但我愿意编写自己的短函数来代替它。
相关问题:
答案 0 :(得分:5)
如果您可以将(a -> b)
功能转换为m a -> m b
,那么您可以使用map
本身。那么,你需要做什么呢? Hoogle非常适合这类事情。搜索(a -> b) -> (m a -> m b)
会得到以下结果:
http://www.haskell.org/hoogle/?hoogle=%28a+-%3E+b%29+-%3E+%28m+a+-%3E+m+b%29
靠近顶部的是fmap
(使用Functor
)和liftM
(使用Monad
)。要么会这样做,但你使用的是monad,那么让我们选择liftM
。因此:
myMap :: Monad m => (a -> b) -> [m a] -> [m b]
myMap f = map (liftM f)
答案 1 :(得分:2)
您的尝试几乎就在那里,您遗失的是return
:
myMap :: (Monad m) => (a -> b) -> [m a] -> [m b]
myMap f = map $ flip (>>=) $ return . f
基本上你需要一种方法来
a
解包m a
- 我们使用>>=
f
应用于f
中包含m
返回值以获取m b
- 我们使用return