在OCaml中做符号

OCaml 是否与 Haskell 的 Do Notation 等效?

另一种说法 - 有没有一种简单的方法可以更轻松地处理嵌套的 monadic 操作......因为这很烦人:

open Batteries
open BatResult.Infix

let () =
  let out = 
    (Ok("one")) >>=
      (fun a -> 
        let b = Ok("two") in
        b >>= (fun c -> 
          print_endline(a);
          print_endline(c);
          Ok(c)
          )) in
  ignore(out)
  

回答

是的,从 OCaml 4.08 开始,可以描述let运算符。例如:

let (let*) x f = BatResult.bind x f 
let (let+) x f = BatResult.map f x

这使得以接近直接风格的风格编写程序成为可能:

let out = 
  let* a = Ok "one" in 
  let* b = Ok "two" in 
  let () = print_endline a in 
  let () = print_endline b in 
  Ok b

您可以描述大量运算符,用于 monad(例如let*forbindlet+for map)、用于应用(例如let+formapand+for product(or zip))等。

否则,可以使用语法扩展,例如https://github.com/janestreet/ppx_let,目前,它提供了比 let 运算符更多的可能性。如果您想要 let 运算符的示例,在Preface(无耻插件)中,我们定义了很多!

编辑:正如@ivg 所说,您可以使用任何一个$????&????*????+????-????/????=????>????@????^????|来定义您的letand运算符。

请参阅:https : //ocaml.org/manual/bindingops.html

  • It also worth mentioning that you're not limited to * and +, but can use (nearly) any operator symbol and more than one if them.

回答

除非您特别尝试混淆您的代码,否则编写没有 do-notation 的 monadic 代码非常容易,例如,如果我们从您的示例中删除过多的1括号,它已经非常可读了,

let v0 =
  Ok "one" >>= fun a ->
  Ok "two" >>= fun c ->
  print_endline a;
  print_endline c;
  Ok c

如果我们使用 let-binding 操作符,例如使用 monads [ 1 , 2 ] 库(也是一个无耻的插件),那么我们可以写得更简洁,

open Monads.Std

open Monad.Result.Error.Syntax
open Monad.Result.Error.Let

let v1 =
  let+ a = Ok "one" and+ b = Ok "two" in
  print_endline a;
  print_endline b;
  b

1) OCaml 通过并列表示应用程序操作(函数对其参数的应用程序和应用程序对其参数的构造函数),例如sin x(not sin(x)) 或Ok 42(not Ok (42)),而且应用程序运算符具有更高的优先级(绑定更紧密) 而不是中缀运算符,因此您可以编写sin x > cos x. lambda 运算符fun <var> -> <expr>与 monadic 运算符很好地链接在一起,例如,

x >>= (fun x -> y >>= (fun y -> x + y))

是相同的

x >>= fun x -> y >>= fun y -> x + y

或者,更多的时候它被写成

x >>= fun x -> 
y >>= fun y ->
x + y

作为对 lambda(抽象)运算符的 let-legacy 的致敬,参见,

let* x = x in
let* y = y in
x + y

和最新版本的 OCaml 甚至允许你双关语的右侧,例如,

let* x in
let* y in
x + y

甚至

let* x and* y in
x + y


以上是在OCaml中做符号的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>