与Functor不同,Monad可以改变形状吗? [英] Unlike a Functor, a Monad can change shape?

查看:118
本文介绍了与Functor不同,Monad可以改变形状吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我总是喜欢以下关于monad相对于函数的权力的直观解释:monad可以改变形状;例如:长度$ fmap f [1,2,3] 总是等于 3



然而,对于monad,长度$ [1,2,3]> ;> = g 通常不会等于 3 。例如,如果 g 被定义为:

  g ::数字a)=> a  - > [a] 
gx = if x == 2 then [] else [x]

然后 [1,2,3]>> = g 等于 [1,3] p>

稍微麻烦我的是 g 的类型签名。看起来不可能定义一个函数来改变输入的形状,使用一般的monadic类型,例如:

  h :: (Monad m,Num a)=> a  - > ma 

MonadPlus或MonadZero类型类具有相关的零元素,而不是 [] ,但现在我们拥有比单子更多的东西。



我是否正确?如果是这样,是否有办法向Haskell的新手表达这种微妙之处。我想让我心爱的单身可以改变形状的短语,只是一个更诚实的接触;如果需要的话。

解决方案


到一个仿函数:monad可以改变形状;一个仿函数不能。

顺便说一句,你在这里略微有些微妙。为了术语的缘故,我将Haskell意义上的 Functor 分成三部分:参数部分由类型参数决定,由 fmap ,不变的部分,比如 State 中的元组构造函数,以及其他任何形式的shape,比如构造函数之间的选择, Nothing Just )或涉及其他类型参数的部分(例如, Reader )。

仅限于函数的参数部分映射函数当然。

Monad 可以根据参数值部分,它不仅仅是改变形状。复制列表中的每个元素或删除前五个元素将改变形状,但过滤列表需要检查元素。



这实际上是如何 Applicative 适合它们 - 它允许您独立组合两个 Functors 的形状和参数值,而不会影响前者。


我是否正确?如果是这样,是否有办法向Haskell的新手表达这种微妙之处。我想让我心爱的单身可以改变形状的短语,只是一个更诚实的接触;如果需要的话。


也许你在这里寻找的微妙之处在于你并没有真正改变任何东西。 Monad 中的任何内容都不会让您明确地弄乱形状。它可以让您根据每个参数值创建新形状,并将这些新形状重新组合为一个新的复合形状。



因此,您将永远受到限制通过可用的方式来创建形状。对于完全通用的 Monad ,您只需要 return ,通过定义可以创建任何形状,这样(>> = return)是身份函数。定义一个 Monad 可以告诉你在给定某种功能的情况下你可以做什么;它不会为你提供这些功能。


I've always enjoyed the following intuitive explanation of a monad's power relative to a functor: a monad can change shape; a functor cannot.

For example: length $ fmap f [1,2,3] always equals 3.

With a monad, however, length $ [1,2,3] >>= g will often not equal 3. For example, if g is defined as:

g :: (Num a) => a -> [a]
g x = if x==2 then [] else [x]

then [1,2,3] >>= g is equal to [1,3].

The thing that troubles me slightly, is the type signature of g. It seems impossible to define a function which changes the shape of the input, with a generic monadic type such as:

h :: (Monad m, Num a) => a -> m a

The MonadPlus or MonadZero type classes have relevant zero elements, to use instead of [], but now we have something more than a monad.

Am I correct? If so, is there a way to express this subtlety to a newcomer to Haskell. I'd like to make my beloved "monads can change shape" phrase, just a touch more honest; if need be.

解决方案

I've always enjoyed the following intuitive explanation of a monad's power relative to a functor: a monad can change shape; a functor cannot.

You're missing a bit of subtlety here, by the way. For the sake of terminology, I'll divide a Functor in the Haskell sense into three parts: The parametric component determined by the type parameter and operated on by fmap, the unchanging parts such as the tuple constructor in State, and the "shape" as anything else, such as choices between constructors (e.g., Nothing vs. Just) or parts involving other type parameters (e.g., the environment in Reader).

A Functor alone is limited to mapping functions over the parametric portion, of course.

A Monad can create new "shapes" based on the values of the parametric portion, which allows much more than just changing shapes. Duplicating every element in a list or dropping the first five elements would change the shape, but filtering a list requires inspecting the elements.

This is essentially how Applicative fits between them--it allows you to combine the shapes and parametric values of two Functors independently, without letting the latter influence the former.

Am I correct? If so, is there a way to express this subtlety to a newcomer to Haskell. I'd like to make my beloved "monads can change shape" phrase, just a touch more honest; if need be.

Perhaps the subtlety you're looking for here is that you're not really "changing" anything. Nothing in a Monad lets you explicitly mess with the shape. What it lets you do is create new shapes based on each parametric value, and have those new shapes recombined into a new composite shape.

Thus, you'll always be limited by the available ways to create shapes. With a completely generic Monad all you have is return, which by definition creates whatever shape is necessary such that (>>= return) is the identity function. The definition of a Monad tells you what you can do, given certain kinds of functions; it doesn't provide those functions for you.

这篇关于与Functor不同,Monad可以改变形状吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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