2016-06-02 10 views
1

私はより良いモナドを理解しようとしています。 Maybe Monad Correctのこの最小実装は正しいですか?LiveScriptを使用してMonadsを理解しようとしています

Maybe = (value) -> 

    @value = value 

Maybe.prototype.ret = -> @value 

Maybe.prototype.bind = (fn) -> 

    if not (@value is null) 

     return fn @value 

    @value 

Maybe.prototype.lift = (fn) -> (val) -> new Maybe fn val 

また、これが正しい場合、一般化する方法について私が混乱している最終的な機能があります。

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

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

    new Maybe f 

今どのようにあなたは、lift3ためlift4これを一般化します.... 出典liftn:http://modernjavascript.blogspot.co.uk/2013/06/monads-in-plain-javascript.html

フォローアップの質問:

あなたが私に結合する方法の簡単な例を与えることができますたぶんモナドと別のモナドを使って簡単に 酒は.thenメソッドでプロミスを保つことができます

モナドの本当の有用性はそれらを変えているからです。

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 

コンストラクタはoptinal {x}パラメータを取ります。

+0

'ret'はインスタンスメソッドであってはなりません。 – rightfold

答えて

1

これはLiveScriptでMaybeモナドを実装するための一つの方法です。 HaskellのMaybeは、その値のコンストラクタのパターンマッチングによって実装されています。 JavaScript(LiveScript)はSumTypesをサポートしていないので、この面白いパラメータはハックです。

今、私たちのようにJustNothingを定義することができます。私たちたぶんテストするには

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

# Nothing :: Maybe x 
Nothing = new Maybe null 

、のsafeSqrt関数を定義してみましょう:

# 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 

このコードはNothingを印刷します。

liftM2は、どのモナドでも動作する関数です。それはpureを使用していますので、それは(私たちの実装でそれが静的関数である)、基礎となるモナドの種類を知っておく必要があります。

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

は、ここではそれを使用することができます方法は次のとおりです。

# 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

こんにちはhomam!その説明に感謝します! – importvault

関連する問題