monad可以做这个OOP可以做什么吗?

时间:2015-10-03 16:15:26

标签: python oop monads

尝试理解monad并想知道它们是否对Python中的数据转换编程有用,我看了很多介绍性的解释。但我不明白为什么单子会很重要。

以下Python代码是否可以很好地表示Maybe monad?

class Some:
    def __init__(self, val):
        self.val=val

    def apply(self, func):
        return func(self.val)


class Error:
    def apply(self, func):
        return Error()


a = Some(1)
b = a.apply(lambda x:Some(x+5))

你能给出一个monad解决方案的例子,它不能转换成这样的OOP代码吗?

(您认为OOP语言中的数据转换monad可能有用吗?)

2 个答案:

答案 0 :(得分:1)

这篇文章讨论了使用Swift作为语言的monads,可以帮助您更好地理解它们:https://github.com/zmokhtar/Memcached-Java-Client

基本观点是monad是一个有三个组件的对象。

  1. 一个构造函数,它可以获取一些其他对象或对象,并创建一个包装该对象的monad。
  2. 一种方法,可以将一个对monad 一无所知的函数应用于其内容,并返回包含在monad中的结果。
  3. 一种方法,可以应用一个函数,该函数接受原始对象并返回包含在monad中的结果,并返回该monad。
  4. 请注意,这意味着如果语言将方法视为第一类对象,并且存在必要的方法,即使Array类也可以是monad。

    如果语言不将方法视为第一类对象,即使它是一种OO语言,它也无法实现Monads。我认为您的混淆可能来自于您使用多范式语言(Python)并假设它是纯粹的OO语言。

答案 1 :(得分:1)

您编写的apply对应于名为bind的monad函数。

鉴于此而构造函数Some(对于广义monad称为unitreturn),您可以定义函数fmapapply推广其他类型的函数:bind提升并使用一个获取普通数据并返回一个monad的函数,fmap这样做是为了从普通数据到纯数据的函数,apply所以对于本身包含在monad中的函数。

我认为,你会遇到问题,定义最后一个monadic操作:joinjoin采用嵌套的monad并将其展平为单个图层。所以这是一个不能在类的所有对象上使用的方法,只能用于具有特定结构的对象。如果您定义join而不是bind,则可以避免使用join(您可以使用bind和身份函数编写bind},因此定义{{1}不方便对于类似数组的monad。数组上的函数更自然地用fmap(在数组上循环并应用函数)和join(采用嵌套数组并展平它)来描述。

我认为如果你可以攻击这些挑战,你可以用你选择的任何语言实现monad。我确实认为monad在许多语言中都很有用,因为可以使用它们来描述许多子计算。它们代表了许多常见问题的已知解决方案,如果它们已经可用,那就意味着您无需进行测试或调试;他们是已经有效的工具。

自己实施它们可以让您使用功能性文献和思维方式来解决问题。这种便利是否值得实施它们的努力取决于你。