2

私はcomposM紙から実装しようとしています 任意のモナドを受け入れてそれに取り組むほぼ合成関数のパターン。Haskell では、コードは次のようになります。

data Expr =
    | Var String
    | Abs String Expr

composExprM :: (Monad m) => (Expr -> m Expr) -> Expr -> m Expr
composExprM f e =
    case e of
        Abs n e -> f e >>= (\e' -> return $ Abs n e')
        _       -> return e

以下のコードでfsharp-typeclassesを使用してみました:

type Expr =
    | Var of string
    | Abs of string * Expr

let rec composExprM f e = match e with
    | Abs (n, e) -> f e >>= (fun e' -> return' <| Abs (n, e'))
    | Var _      -> return' e

しかし、型推論エラーが発生します:

> Could not resolve the ambiguity inherent in the use of the operator 'instance' at or near this program point. Consider using type annotations to resolve the ambiguity.

> Type constraint mismatch when applying the default type 'obj' for a type inference variable. No overloads match for method 'instance'. The available overloads are shown below (or in the Error List window). Consider adding further type constraints

> Possible overload: 'static member Return.instance : _Monad:Return * Maybe<'a> -> ('a -> Maybe<'a>)'. Type constraint mismatch. The type 
      obj    
  is not compatible with type
    Maybe<'a>    
  The type 'obj' is not compatible with the type 'Maybe<'a>'.

> etc.....

fsharp-typeclasses で達成しようとしていることは可能ですか? または、特定のモナドのみを使用するように関数を制限する必要がありますか?

4

1 に答える 1

3

この手法を使用するポリモーフィック関数はインラインにする必要があることに注意してください。そこに「魔法」が存在します。

inlineそのため、後にキーワードを追加するだけlet recでコンパイルされます。

関数が期待どおりに動作するかどうかを教えてください。後でその紙を見てみましょう。

サンプルには、どのモナドでも動作するように定義された多くの関数が含まれています。それが私がこのプロジェクトを始めた主な動機でした。

于 2013-07-19T11:39:08.127 に答える