我们怎么知道一个应用程序不能是Monad? [英] How could we know that an applicative can't be a Monad?

查看:67
本文介绍了我们怎么知道一个应用程序不能是Monad?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从验证示例( https://hackage.haskell.org/package/Validation),我试图获得一种直觉来检测应用程序为何/为什么不能成为Monad(

From the example of Validation (https://hackage.haskell.org/package/Validation), I'm trying to get an intuition of detecting how/why an applicative could not be a Monad (Why can AccValidation not have a Monad instance?)

你能挑战我的推理吗?

我以处理联接(m(m b)-> m b)的方式思考单子,让我们通过Validation这样的例子来加深我的理解:

I think about a monad in the way we handle behind the join (m ( m b) -> m b), let's develop my understanding with an example like Validation:

,函子结构为(Validation err).当您查看Monad绑定的定义并专门化Validation的类型时,您将获得以下信息:

in data Validation err a, the functor structure is (Validation err). When you look at the definition of the bind for Monad and specializing the types for Validation you get the following :

(>>=)  :: m a -> (a -> m b) -> m b
(>>=)  :: (Validation err) a -> (  a -> (Validation err) b) -> (Validation err) b

如果您的beta减少(>> =),您将获得:

if you beta reduce (>>=) you'll get :

m a -> (a -> m b) -> m b // if we apply (m a) in the monadic function  
m ( m b) -> m b

然后得到(>> =)为m b的结果,您将使用join:

then to get the result of (>>=) which is m b, you'll use join :

join              :: (Monad m) => m (m a) -> m a
join x            =  x >>= id

如果您使用的类型,您将得到:

If you play with the types you'll get :

join m ( m b ) = m ( m b) >>= (\(m b) -> m b -> m b) which gives m b

因此,只要联接只删除最外层结构,就仅通过序列保留/传输最内层类型中的值(最内层函子的值).

So that join just drop the outermost structure, only the value in the innermost type (the value of the innermost functor) is kept/transmitted through the sequence.

在monad中,我们无法将某些信息从函子结构(例如Validation err)传递给下一个操作",我们唯一可以传递的就是值.您可以使用该结构的唯一想法就是缩短序列以从中获取信息.

In a monad we can't pass some information from the functor structure (e.g Validation err) to the next 'action', the only think we can pass is the value. The only think you could do with that structure is short-circuiting the sequence to get information from it.

您无法对函子结构中的信息执行一系列操作(例如,积累诸如错误之类的东西.)

You can't perform a sequence of action on the information from the functor structure (e.g accumulating something like error..)

所以我要说的是,某个应用程序以某种结构上的逻辑来挤压其结构时,可能会因为无法成为Monad而产生怀疑?

So I would say that an applicative that is squashing its structure with some logic on its structure could be suspicious as not being able to become a Monad ?

推荐答案

这并不是真正的答案,但是评论太久了.

This isn't really an answer, but it's too long for a comment.

以及该主题中其他引用的讨论都是相关的.我认为这个问题有点倒退:所有Monad自然会产生一个Applicative(其中pure = return等);问题是大多数用户期望/假设(其中类型为实例Monad) Applicative实例在语义上等同于Monad产生的实例.

This and other referenced discussions in that thread are relevant. I think the question is posed sort of backwards: all Monads naturally give rise to an Applicative (where pure = return, etc); the issue is that most users expect/assume that (where a type is instance Monad) the Applicative instance is semantically equivalent to the instance to which the Monad gives rise.

Applicative类中将其记录为一种法律,但我并不完全相信这是合理的.这种说法似乎是因为ApplicativeMonad不能以这种方式达成共识会令人困惑.

This is documented in the Applicative class as a sort of law, but I'm not totally convinced it's justified. The argument seems to be that having an Applicative and Monad that don't agree in this way is confusing.

我使用Validation的经验是,做任何大事都是一场噩梦,这既是因为符号变得一团糟,又是因为您发现自己有一些数据依赖性(例如,您需要根据上一节的解析).您最终定义了bindV,其行为类似于Error monad >>=,因为适当的Monad实例被认为是可疑的.

My experience using Validation is that it's a nightmare to do anything large with it, both because the notation becomes a mess and because you find you have some data dependencies (e.g. you need to parse and validate one section based on the parse of a previous section). You end up defining bindV which behave like an Error monad >>= since a proper Monad instance is considered dubious.

,但是像这样使用Monad/Applicative对实现了您想要的:特别是在使用ApplicativeDo时(我想;还没有尝试过),在Monadic中编写解析器(例如)的效果风格是,您可以根据解析代码的数据依赖性在每个级别上累积尽可能多的错误. Haxl可以说以类似的方式捏造了这个法律".

And yet using a Monad/Applicative pair like this does what you want: especially when using ApplicativeDo (I imagine; haven't tried this), the effect of writing your parser (e.g.) in Monadic style is that you can accumulate as many errors as possible at every level, based on the data dependencies of your parsing code. Haxl arguably fudges this "law" in a similar way.

对于Applicative的其他类型,我没有足够的经验,但是对于Monad的其他类型,我没有足够的经验来知道何时可以"让Applicative以这种方式不同意. Validation似乎明智地工作完全是任意的.

I don't have enough experience with other types that are Applicative but not Monad to know whether there's a sensible rule for when it's "okay" for the Applicative to disagree in this way. Maybe it's totally arbitrary that Validation seems to work sensibly.

我不确定如何直接回答您的问题.我认为您首先要从Applicative类文档底部记录的法律开始,然后翻转它们,这样您就可以得到:

I'm not sure how to directly answer your question. I think you start by taking the laws documented at the bottom of Applicative class docs, and flip them, so you get:

 return = pure
 ap m1 m2 = m1 <*> m2

如果apMonad的方法,并且上面的内容是一个最小的完整定义,那么您只需测试上面的内容是否通过Monad法则来回答关于任何Applicative的问题,但是当然不是这种情况.

If ap were a method of Monad and the above was a minimal complete definition then you'd simply have to test whether the above passed the Monad laws to answer your question for any Applicative, but that's not the case of course.

这篇关于我们怎么知道一个应用程序不能是Monad?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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