2016-06-02 17 views
1

zu verstehen Ich versuche, Monaden besser zu verstehen. Ist diese minimale Implementierung einer Maybe Monad Correct?Versuchen, vielleicht Monaden mit LiveScript

auch wenn dies korrekt ist - gibt es eine letzte Funktion, die ich bin verwirrt darüber, wie zu verallgemeinern.

Maybe.prototype.lift2 = (fn) -> (M1, M2) -> 

    f = M1.bind ((val1) -> M2.bind (val2) -> fn val1, val2) 

    new Maybe f 

Nun, wie Sie dies tun verallgemeinern für lift3, lift4 .... liftn Quelle: http://modernjavascript.blogspot.co.uk/2013/06/monads-in-plain-javascript.html

Follow Up Frage:

Könnten Sie mir ein einfaches Beispiel, wie das kombinieren Vielleicht Monad mit einem anderen Monad für die Einfachheit Willen lassen Sie es ein Versprechen mit einer .then Methode

Da die tatsächliche Nützlichkeit der Monaden sie verändern.

+0

'ret' sollte keine Instanzmethode sein. – rightfold

Antwort

1

Dies ist ein Weg Maybe Monade in Livescript der Umsetzung:

class Maybe 
    ({x}:hasValue?) -> 

    # map :: [Maybe a -> ] (a -> b) -> Maybe b 
    @map = (f) -> 
     if !hasValue then Nothing else Just (f x) 

    # bind :: [Maybe a -> ] (a -> Maybe b) -> Maybe b 
    @bind = (f) -> 
     if !hasValue then Nothing else f(x) 

    # toString :: [Maybe a -> ] String 
    # note here it's not necessary for toString() to be a function 
    # because Maybe is can only have either one these values: 
    # Nothing or Just x 
    @show = 
     if !hasValue then 'Nothing' else "Just #{x.toString!}" 

    # static method 
    @pure = (x) -> Just x 

Der Konstruktor nimmt eine optinal {x} Parameter. Maybe in Haskell wird durch Mustervergleich auf seinen Wertkonstanten implementiert. Dieser lustige Parameter ist ein Hack, da JavaScript (LiveScript) SumTypes nicht unterstützt.

Jetzt können wir definieren Just und Nothing als:

# Just :: x -> Maybe x 
Just = (x) -> new Maybe {x} 

# Nothing :: Maybe x 
Nothing = new Maybe null 

unsere Um zu testen, Vielleicht wollen wir definieren eine safeSqrt Funktion:

# safeSqrt :: Number -> Maybe Number 
safeSqrt = (x) -> 
    if x > 0 then Just (Math.sqrt x) else Nothing 

# operation :: Maybe Number 
operation = do -> 
    a = Just 4 
    .map (x) -> x * -16 
    .bind safeSqrt 

console.log operation.show 

Dieser Code Nothing gedruckt wird.

liftM2 ist eine Funktion, die auf jeder Monade funktioniert. Es muss die Art des zugrundeliegenden Monade wissen, weil es verwendet pure (das in unserer Implementierung eine statische Funktion ist):

# liftM2 :: Monad m => (a -> b -> c) -> m a -> m b -> m c 
liftM2 = (monadType, f, m1, m2) --> 
    x1 <- m1.bind 
    x2 <- m2.bind 
    monadType.pure (f x1, x2) 

Hier ist, wie wir es verwenden können:

# operation :: Maybe Number 
operation = do -> 
    a = Just 4 
    .map (x) -> x * 16 
    .bind safeSqrt 
    b = safeSqrt 81 

    liftM2 Maybe, (+), a, b 

console.log operation.show 

Code in JSBin

+0

Hey homam! Danke für diese Erklärung! – importvault