【问题标题】:Writing a custom map function编写自定义地图功能
【发布时间】:2013-10-07 02:26:53
【问题描述】:

现在 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]

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

相关问题:

Mapping a function over two input lists

【问题讨论】:

    标签: haskell monads


    【解决方案1】:

    如果您可以将(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)
    

    【讨论】:

    • 这可以减少。
    • 看起来liftM 是我正在寻找的库函数。
    【解决方案2】:

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

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

    基本上你需要一种方法来

    • 从m a 解开a - 我们使用>>= 来实现这一点
    • 申请f
    • 将f 的返回值包装在m 中以获取m b - 我们为此使用return

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-06
      • 2022-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-17
      • 2020-02-08
      • 1970-01-01
      相关资源
      最近更新 更多