2

现在 Haskell 库中可能有一些东西可以做我想做的事。我已经够菜鸟了,不知道更好,我正在尝试使用我知道的工具编写自定义地图功能。类型签名需要是

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

where在应用于每个 Monad 中的每个值myMap f as后返回一个列表。fas

我的第一次尝试是

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

然而,这有一个类型签名

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

这太接近我需要的了,我可以尖叫。现在我需要一些关于如何从这里继续的提示。我真的希望它像库函数一样简单,但我愿意编写自己的短函数来代替它。

相关问题:

在两个输入列表上映射函数

4

2 回答 2

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)
于 2013-10-07T02:43:55.027 回答
2

你几乎在你的尝试中,你缺少的是return

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

基本上你需要一种方法

  • unwrap afrom m a- 我们使用>>=
  • 适用f于它
  • 包装f返回值m以获取m b- 我们使用return
于 2013-10-07T04:48:23.897 回答