在Haskell中如何以及为什么将ap定义为liftM2 id [英] How and why is ap defined as liftM2 id in Haskell

查看:111
本文介绍了在Haskell中如何以及为什么将ap定义为liftM2 id的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在试图更好地理解Applicative的同时,我研究了< *>的定义,它倾向于被定义为ap,后者又定义为:

  ap ::(Monad m)=> m(a  - > b) - > m a  - > mb 
ap = liftM2 id

查看liftM2和id的类型签名,即:

  liftM2 ::(Monad m)=> (a1→a2→r)→> m a1  - > m a2  - > m r 
id :: a - > a

我不明白如何通过传入id,类型签名的相关部分似乎从(a1 - > a2 - > r) - > (a - > b)。我在这里错过了什么?

解决方案

类型变量 a from id 可以以任何类型实例化,在这种情况下,该类型是 a - > B'/ code>。因此我们在(a - > b) - >>处实例化 id (a - > b)。现在来自 liftM2 的类型变量 a1 正在实例化为(a - > b) , a2 正在实例化为 a r 正在被实例化为 b

把它们放在一起, liftM2 ((a - > b )→>(a→b))→> m(a - > b) - > m a - > m b liftM2 id :: m(a - > b) - > m a - > m b


Whilst trying to better understand Applicative, I looked at the definition of <*>, which tends to be defined as ap, which in turn is defined as:

ap                :: (Monad m) => m (a -> b) -> m a -> m b
ap                =  liftM2 id

Looking at the type signatures for liftM2 and id, namely:

liftM2  :: (Monad m) => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r
id                      :: a -> a

I fail to understand how just by passing in id, the relevant part of the type signature seems to transform from (a1 -> a2 -> r) -> m a1 to m (a -> b). What am I missing here?

解决方案

The type variable a from id can be instantiated at any type, and in this case that type is a -> b.

So we are instantiating id at (a -> b) -> (a -> b). Now the type variable a1 from liftM2 is being instantiated at (a -> b), a2 is being instantiated at a, and r is being instantiated at b.

Putting it all together, liftM2 is instantiated at ((a -> b) -> (a -> b)) -> m (a -> b) -> m a -> m b, and liftM2 id :: m (a -> b) -> m a -> m b.

这篇关于在Haskell中如何以及为什么将ap定义为liftM2 id的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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