2016-09-10 8 views
5

okamlにフリーモナドライブラリーを書き込もうとしていますが、これはhaskellのControl.Monad.Freeの後にありますが、hoistFreeの実装では一点に止まっています。ocamlのタイプを拡大

hoistFree :: Functor g => (forall a. f a -> g a) -> Free f b -> Free g b 
hoistFree _ (Pure a) = Pure a 
hoistFree f (Free as) = Free (hoistFree f <$> f as) 

ここは翻訳を試みたものです。

残念ながら、私はgのタイプを正しく広げていないと言ってエラーが発生します。

Error: This definition has type ('b m t -> 'b m t) -> 'b m -> 'b m 
     which is less general than 'a. ('a t -> 'a t) -> 'b m -> 'b m 

私は関数型注釈を挿入しない場合、すべてが正常に動作しますが、エラーメッセージが言うように、その後、私はFのための一般的なタイプを得ることはありません。 どこに問題がありますか?どのように私はfの種類を広げることができますか?

答えて

3

私はOCamlのに非常に精通していないが、私は前者は基本的なポリモーフィック型で

let rec hoistfree : ('b. ('b t -> 'b t)) -> 'a m -> 'a m = 

let rec hoistfree : 'b. (('b t -> 'b t) -> 'a m -> 'a m) = 

代わりの

として

let rec hoistfree : 'b.('b t -> 'b t) -> 'a m -> 'a m = 

が解析されることを信じて、後者は、Hindley-Milnerよりも型システムからのより多くのサポートを必要とするrank2型である。

IIRCでは、後者を実現するためにカスタムラッパーデータ型を定義する必要があります。たとえば:

type poly = { polyf: 'a . 'a -> 'a } ;; 

let foo (x: poly): int = x.polyf 4;; 
let bar: poly = { polyf = fun x -> x } ;; 

let _ = print_string ("hello "^string_of_int (foo bar));; 
+0

回答ありがとうございます。私はまだ私の特定の設定であなたのアイデアを実装しようとしています。 – stackman

関連する問題