1

私はモナドをよりよく理解しようとしています。これは Maybe Monad Correct の最小限の実装ですか?

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ソースでどのように一般化しますか?

フォローアップの質問:

簡単にするために、Maybe Monad を別の Monad と組み合わせる方法の簡単な例を教えてください.then

モナドの真の有用性はそれらを変換することです。

4

1 に答える 1

1

Maybeこれは、LiveScript でモナドを実装する 1 つの方法です。

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

コンストラクターは、オプションの{x}パラメーターを取ります。MaybeHaskell では、値コンストラクターのパターン マッチングによって実装されます。JavaScript (LiveScript) は SumTypes をサポートしていないため、この面白いパラメータはハックです。

Justこれで、 andNothingを次のように定義できます。

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

# Nothing :: Maybe x
Nothing = new Maybe null

safeSqrtMaybe をテストするために、関数を定義しましょう。

# 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

JSBin のコード

于 2016-06-22T14:25:53.930 に答える