这是一个Functor还是Monad? [英] Is this a Functor or Monad?

查看:79
本文介绍了这是一个Functor还是Monad?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在C#中实现了我自己的Promise结构,并且想要在Haskell中测试这个概念,所以在经过一些严重的大脑训练之后(我还是非常新的),我制作了

  data Promise fa = PendingPromise f | ResolvedPromise a | BrokenPromise派生(显示)

类未来p其中
以后::(b - > c) - > p(a - > b)b - > p(a - > c)c
resolve :: p(a - > b)a - > a - > p(a - > b)b

实例未来承诺其中
晚些时候g(PendingPromise f)= PendingPromise(g。f)
以后g(ResolvedPromise a)= ResolvedPromise (ga)
resolve(PendingPromise f)a = ResolvedPromise(fa)

写这个数据类型 Promise fa 真是头疼。无论如何,后来的方法似乎是某种应用函子,Promise应该是Monads。是否有可能使 Promise 某个 class 的实例并获得此功能,而不是实现我自己的Future类?






编辑
感谢@bheklilr 稍后函数被证明是伪装的 fmap ,只是对数据类型进行了一些重新定义

  data Promise ab = PendingPromise(a  - > b)| ResolvedPromise b | BrokenPromise 

实例Functor(Promise c)其中
fmap f(PendingPromise g)= PendingPromise(f。g)
fmap f(ResolvedPromise a)= ResolvedPromise(fa)
fmap f BrokenPromise = BrokenPromise

知道(Promise a)是一个Functor,它更容易看看为什么是单子。

解决方案

是的,它是一个monad。最简单的方法是观察 Promise fa≅Maybe(或fa),因此它也同构于具有已经证明的标准Monad实例的变换器等效项。 p>

  type Promise'f = ErrorT f也许

promise2Trafo :: Promise fa - > Promise'f a
promise2Trafo(PendingPromise f)= ErrorT。只要$ f
promise2Trafo(ResolvedPromise a)= ErrorT。 Just $ Right a
promise2Trafo BrokenPromise = ErrorT Nothing

trafo2Promise :: Promise'f a - > Promise f a
trafo2Promise = ... - 'promise2Trafo`的简单反转

实例Applicative Promise其中
pure = trafo2Promise。纯
fp * xp = trafo2Promise $ promise2Trafo fp< *> promise2Trafo xp

等等。


I implemented my own Promise structure in C# and wanted to test the concept in Haskell so after some severe brain workouts (still very new to this) I produced

data Promise f a =  PendingPromise f | ResolvedPromise a | BrokenPromise deriving( Show )

class Future p where
        later :: (b -> c) -> p (a -> b) b -> p (a -> c) c
        resolve :: p (a -> b) a -> a -> p (a -> b) b

instance Future Promise where
        later g (PendingPromise f) = PendingPromise (g . f)
        later g (ResolvedPromise a) = ResolvedPromise (g a)
        resolve (PendingPromise f) a = ResolvedPromise (f a)

Figuring out how to write this datatype Promise f a was a real headache.

Anyway, the later method seems to be some sort of Applicative Functor and Promises are supposed to be Monads. Is it possible for me to make Promise an instance of some class and get this functionality instead of implementing my own class Future?


Edit Thanks to @bheklilr the later function was proven to be fmap in disguise with a little redefinition of the datatype

data Promise a b =  PendingPromise (a -> b) | ResolvedPromise b | BrokenPromise

instance Functor (Promise c) where
    fmap f (PendingPromise g) = PendingPromise (f . g)
    fmap f (ResolvedPromise a) = ResolvedPromise (f a)
    fmap f BrokenPromise = BrokenPromise

Knowing that (Promise a) is a Functor, it is easier to see why is a Monad.

解决方案

Yes, it is a monad. The easiest way to see this is observing Promise f a ≅ Maybe (Either f a), thus it's also isomorphic to the transformer equivalent which has an already-proven standard monad instance.

type Promise' f = ErrorT f Maybe

promise2Trafo :: Promise f a -> Promise' f a
promise2Trafo (PendingPromise f) = ErrorT . Just $ Left f
promise2Trafo (ResolvedPromise a) = ErrorT . Just $ Right a
promise2Trafo BrokenPromise = ErrorT Nothing

trafo2Promise :: Promise' f a -> Promise f a
trafo2Promise = ... -- straightforward inverse of `promise2Trafo`

instance Applicative Promise where
  pure = trafo2Promise . pure
  fp <*> xp = trafo2Promise $ promise2Trafo fp <*> promise2Trafo xp

and so on.

这篇关于这是一个Functor还是Monad?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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