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 实现的目标是什么?还是我必须将函数限制为仅使用特定的 monad?

4

1 回答 1

3

请记住,使用这种技术的多态函数应该是内联的,这就是“魔法”所在的地方。

因此,只需在后面添加inline关键字let rec,它就会编译。

请让我知道该功能是否按预期运行。我稍后会看看那篇论文。

在示例中,您会发现许多定义为与任何 Monad 一起使用的函数。这是我开始这个项目的主要动机。

于 2013-07-19T11:39:08.127 回答