在Haskell中实现liftM2 [英] Implementing liftM2 in Haskell

查看:74
本文介绍了在Haskell中实现liftM2的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为了练习,我一直在尝试仅使用功能ap和liftM来实现liftM2.这些功能定义为:

For an exercise, I've been trying to implement liftM2 using just the functions ap and liftM. The functions are defined as:

ap :: IO (a -> b) -> IO a -> IO b
liftM :: (a -> b) -> IO a -> IO b

liftM2 :: (a -> b -> c) -> IO a -> IO b -> IO c

我可以轻松地使用do表示法来完成liftM2,但不确定如何仅使用ap和liftM来完成.我当时想让结果看起来像这样:

I can easily do liftM2 using do notation but not sure how to do it using just ap and liftM. I was thinking of having the result be something that looks like this:

liftM2 f a b = liftM (_) (ap _ a)

我对如何弄乱f感到困惑,f是(a-> b-> c),这样我就可以将a转到b并将b转到c.谢谢.

I'm confused on how to mess with f, which is (a -> b -> c) such that I can just turn a to b and b to c. Thank you.

推荐答案

一般模式正在转变

liftMn f a1 ... an

进入

f <$> a1 <*> ... <*> an
-- i.e., more precisely
(... ((f <$> a1) <*> a2) ... <*> an)

其中<$>liftM(又名fmap),而<*>ap.

where <$> is liftM (AKA fmap) and <*> is ap.

因此,对于n=2,我们得到

(f `liftM` a1) `ap` a2
-- i.e.
ap (liftM f a1) a2

检查类型:

f :: t1 -> t2 -> r
liftM f :: IO t1 -> IO (t2 -> r)
a1 :: IO t1
liftM f a1 :: IO (t2 -> r)
ap (liftM f a1) :: IO t2 -> IO r
a2 :: IO t2
ap (liftM f a1) a2 :: IO r

此处的主要思想是将f :: t1 -> t2 -> r读为f :: t1 -> (t2 -> r),以便跟随liftM f :: IO t1 -> IO (t2 -> r).注意IO中的函数类型.然后,我们可以使用ap->上分发" IO,以便我们可以应用a2 :: IO t2.

The key idea here is to read f :: t1 -> t2 -> r as f :: t1 -> (t2 -> r) so that liftM f :: IO t1 -> IO (t2 -> r) follows. Note the function type inside the IO. We can then "distribute" IO over -> using ap, so that we can apply a2 :: IO t2.

这篇关于在Haskell中实现liftM2的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆