【问题标题】:SML Option Monad (bind operator not working)SML Option Monad(绑定运算符不工作)
【发布时间】:2016-06-28 14:38:16
【问题描述】:

我想在 SML 中实现 Option Monad,所以我可以像在 haskell 中一样使用它们。我所做的,不起作用。

infix 1 >>=
signature MONAD =
sig
    type 'a m 
    val return : 'a -> 'a m 
    val >>= : 'a m * ('a -> 'b m) -> 'b m 
end;

structure OptionM : MONAD =
struct
    type 'a m = 'a option
    val return = SOME
    fun x >>= k = Option.mapPartial k x
end;

val x = OptionM.return 3;
x (OptionM.>>=) (fn y => NONE);

结果:

stdIn:141.1-141.31 Error: operator is not a function [tycon mismatch] 
operator: int OptionM.m
in expression:
x OptionM.>>=

我该怎么做才能使最后一行正常工作?

【问题讨论】:

  • 这是一个solution - 只是open OptionM
  • val op >>= = OptionM.>>=

标签: operators bind monads sml


【解决方案1】:

与 Haskell 不同,合格的中缀运算符(例如 A.+Option.>>=)在 SML 中不是中缀。您需要不合格地使用它们,例如通过打开模块或在本地重新绑定它。

顺便说一句,您可能希望将>>= 定义为右关联,即使用infixr

此外,SML 具有比 Haskell 更严格的优先级规则。这将使将 >>= 的多个用法与 lambda 链接起来会更加乏味,因为您必须在右侧将每个 fn 括起来:

foo >>= (fn x => bar >>= (fn y => baz >>= (fn z => boo)))

【讨论】:

  • 引用The Definition of Standard ML (Revised),§2.6:“(请注意,合格的标识符永远不会有中缀状态。)”
  • 我对这个答案的第二和第三段有点困惑,因为在我看来 >>= 运算符应该是左关联的(就像在 Haskell 中一样),此外它似乎确实可以在 SML 中使用匿名函数而不需要堆叠括号。但我知道 Andreas 是 SML 专家,所以我可能遗漏了什么。
  • @xyz,你说得对,我不知道我在想什么关于关联性!感谢您的指正。但是您绝对需要括号:x <op> fn y => e 在 SML 中是不合法的,因为根据其完整语法(SML 定义的附录 B),中缀运算符仅允许进一步的应用程序或原子表达式作为操作数。如果您遇到接受它的实现,我很想知道。
  • @AndreasRossberg 谢谢。关于括号,我的意思是左关联意味着我们可以写x >>= (fn y => e) >>= (fn z => e),那么 SML 并没有真正造成任何丑陋/乏味。即最后没有“指甲剪报”,因为人们在 Lisp 中无情地称呼它们。
猜你喜欢
  • 2011-12-19
  • 1970-01-01
  • 1970-01-01
  • 2020-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-28
  • 2015-01-12
相关资源
最近更新 更多