单子是否具有流畅接口?

10

对不起,如果这个问题看起来很愚蠢,但我对函数式编程的整个世界还很陌生,所以我需要一些 StackOverflow 社区的专家帮助我理解。

据我了解,对于一个单子(monad)的操作返回也是一个单子。这是否意味着单子有流畅接口(fluent interface),每个应用在单子上的函数,在将其封装的变量进行某些操作后,都会返回该单子?


2
我认为这不是一个有意义的问题——流畅接口已经足够作为面向对象(OO)概念,将其与单子进行比较(至少在Haskell中,单子是一种“类型类”,与OO类非常不同)并没有特别有用。(但我可能错了。) - Antal Spector-Zabusky
是的,我不确定如何提出这个问题,因为我一直都是面向对象的程序员。如果我说得不清楚,请见谅。 - user193476
这个问题很有道理,但我不确定它有一个好的答案。但是,我没有做过足够多的OO编程来给你一个有用的答案。 - Antal Spector-Zabusky
如果你将单子概念扩展到面向对象编程中,它就有意义了。特别是像 Promises 这样的概念非常“单子化”,而且一些人已经将 JQuery 包装器作为单子的例子之一。通常这些也具有流畅的接口。 - Garrett Motzner
2个回答

8
您可能在指称与单子相关的绑定操作符,其中可以从一个单子值开始,将其绑定到一个单子函数,并最终得到另一个单子值。这很像一种“流畅方法”(或由其组成的“流畅接口”),返回一个“this”指针或引用,但您在那里会错过的是,单子函数不需要返回与输入值相同类型的单子值。流畅方法约定返回相同类型的值,以便继续链接调用,这些调用对正在准备的实例(或实例)都是有效的
单子绑定操作符的签名更像是这样:
M[a] -> (a -> M[b]) -> M[b]

也就是说,“返回值”可能与第一个输入值的类型不同。只有当提供的函数具有以下类型时,才相同:

(a -> M[a])

这完全取决于单子函数的类型,更具体地说,是单子函数的返回类型。

如果你将接受的单子函数的定义域限制为与提供给bind操作符的单子值相同的类型,则确实会得到类似流畅接口的行为。


虽然您已经澄清了单子的行为方式,但看起来我仍然需要做更多的研究!谢谢并接受。 - user193476

1

根据我所知道的流畅接口,它们主要通过使用方法链使代码“可读性更好”。举个例子:

Date date = date()
    .withYear(2008)
    .withMonth(Calendar.JANUARY)
    .withDayOfMonth(15)
    .toDate();

使用Haskell do-notation版本(使用虚构的日期API),代码示例如下:

do date
   withYear 2008
   withMonth JANUARY
   withDayOfMonth 15
   toDate

无论这个基于do-notation的DSL或其他类似DSL是否符合“流畅接口”的标准,可能需要讨论,因为没有正式定义“流畅接口”是什么。如果它读起来像这样,那么我会说它足够接近了。
请注意,这并不完全特定于单子;如果您不要求方法调用,单子可以具有流畅的接口,但这取决于函数名称和API的使用方式。

实际上,你不需要在末尾使用“toDate”。 - gleber

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接