2016-06-26 23 views
4

Ich möchte Option Monad in SML implementieren, damit ich sie genauso verwenden kann, wie sie in Haskell verwendet werden können. Was ich getan habe, funktioniert nicht.SML-Option Monad (Bind-Operator funktioniert nicht)

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); 

Ergebnis:

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

Was kann ich tun, um die letzte Zeile der Arbeit zu machen?

+2

Hier ist eine [Lösung] (http://stackoverflow.com/a/ 14129095/2747511) - nur 'open OptionM'. –

+1

Oder 'val op >> = = OptionM. >> ='. –

Antwort

6

Im Gegensatz zu Haskell sind qualifizierte Infix-Operatoren (wie A.+ oder Option.>>=) in SML nicht infix. Sie müssen sie uneingeschränkt verwenden, z. indem Sie das Modul entweder öffnen oder lokal neu binden.

Btw, wahrscheinlich möchten Sie >>= als rechtsassoziativ definieren, d. H. infixr verwenden.

Außerdem hat SML strengere Vorrangregeln als Haskell. Das macht es etwas langweilig Kette mehrere Verwendungen von >>= mit Lambda-Ausdrücke, weil Sie jedes fn auf dem rechten Flügel parenthesise haben:

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

Ein Zitat aus [Die Definition von Standard-ML (Überarbeitet)] (http://sms-family.org/sml97-defn.pdf), §2.6: "(Beachten Sie, dass qualifizierte Bezeichner niemals Infix-Status haben.)" –