OCaml - 为什么 Either 不是 Monad
OCaml - Why is Either not a Monad
我是 OCaml 的新手,但曾使用过 Rust、Haskell 等,当我尝试在 Either
上实现 bind
时感到非常惊讶,它似乎没有任何通用实现 bind
实现。
- JaneStreet 的
Base
是 missing it
- 我假设标准库是 missing it
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 c
到 Either 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
我是 OCaml 的新手,但曾使用过 Rust、Haskell 等,当我尝试在 Either
上实现 bind
时感到非常惊讶,它似乎没有任何通用实现 bind
实现。
- JaneStreet 的
Base
是 missing it - 我假设标准库是 missing it
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 c
到 Either 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