2

我喜欢计算表达式,但我会犯一些简单的错误,比如忘记 return 关键字或 ! 关于 let! 然后返回!,或者我只是忘记写do!。状态单子经常发生这种情况,我倾向于忘记状态,只关注我定义的单子运算符。

我有时会确保我的单子运算符返回一个“单子类型”而不是“匿名”函数的类型。这有助于跟踪我健忘的打字,但并不是很理想。有人有更好的技巧吗?

4

1 回答 1

3

给定一个典型的 monad,如果您缺少!after 关键字,您的代码不应该编译,因为类型不会起作用。例如:

let sum = async {
  let x = async { return 1 }
  let y = async { return 2 }
  return x + y
}

这不会编译,因为您尝试添加两个Async<int>s,但如果您将lets更改为 s,它将编译let!

同样,要识别缺失return的 s,只需注意编译器警告消息和奇怪的单子类型:

let sum = async {
  let! x = async { return 1 }
  let! y = async { return 2 }
  x + y // warning FS0020
}

在这种情况下,sum是一个Async<unit>,当您尝试在代码的其他地方使用它时应该很明显。或者,您可以使用类型注释立即捕获此问题:

let sum : Async<int> = async { // error FS0001: type mismatch
  let! x = async { return 1 }
  let! y = async { return 2 }
  x + y // warning FS0020
}
于 2010-12-07T16:55:16.157 回答