2016-09-10 5 views
5

okaml에서 무료 monad 라이브러리를 작성하려고합니다. 다음은 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의 유형을 올바르게 확장하지 못한다는 오류가 발생합니다. 내가 함수 타입 주석을 삽입하지 않지만, 다음 오류 메시지가 말한대로, 나는 F의 일반적인 유형을하지 않는 경우

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의 유형을 넓힐 수 있습니까?

답변

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보다 형식 시스템에서 더 많은 지원이 필요한 순위 2 유형입니다.

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