OCaml - 为什么 Either 不是 Monad

OCaml - Why is Either not a Monad

我是 OCaml 的新手,但曾使用过 Rust、Haskell 等,当我尝试在 Either 上实现 bind 时感到非常惊讶,它似乎没有任何通用实现 bind 实现。

bind 是我达到的第一个功能......甚至在 match 之前,实现起来似乎很容易:

let bind_either (m: ('e, 'a) Either.t) (f: 'a -> ('e, 'b) Either.t): ('e, 'b) Either.t =
  match m with
  | Right r -> f r
  | Left l -> Left l

我是不是漏掉了什么?

因为我们更喜欢更具体的Result.t,它对正常状态和异常状态都有明确的名称。而且,一般来说,Either.t 在 OCaml 程序员中并不像往常一样非常流行,可以将更专业的类型与变体名称一起使用,以更好地传达任一分支的特定于域的目的。另外值得一提的是,Either 是最近才被引入 OCaml 标准的,刚好是 4.12,所以它可能会更受欢迎。

正如@ivg 所提到的,Either 对于标准库来说是相对较新的,通常人们更愿意使用更有意义的类型。例如,Result 用于错误处理。 还有另一种观点,同样适用于Result。 Monad 作用于由一种类型参数化的类型。 在 Haskell 中,这不太明显,因为可以部分应用类型构造函数。因此; bind:: (a -> b) -> Either a -> Either b 允许您从 Either a cEither b c

在尝试通过参数化模块(术语 ML 意义上的函子)概括 monad 的行为时,必须“欺骗”自己进行标准化,例如 option 的处理(一种 arity 1)和 either(或 result)是 arity 2.

有几种方法。例如,表达多个接口来描述一个 monad。例如描述 Monad2 并根据 Monad2 描述 Monad,就像在基础库 (https://ocaml.janestreet.com/ocaml-core/latest/doc/base/Base/Monad/index.html)

中所做的那样

Preface we used a rather different (and perhaps less generic) approach. We leave it to the user to set the left parameter of Either (via a functor) (and the right parameter for Result): https://github.com/xvw/preface/blob/master/lib/preface_stdlib/either.mli

但是,我们并没有失去改变计算左侧类型的能力,因为 Either 也有一个 Bifunctor 模块,它允许我们改变两个参数的类型。该对话在以下主题中进行了广泛描述:https://discuss.ocaml.org/t/instance-modules-for-more-parametrized-types/5356/2