2015-02-13 4 views
2

Вот что переводчик дает мне:Как ввести `let rec f g = g f` в OCaml?

# let rec f g = g f ;; 
Error: This expression has type ('a -> 'b) -> 'c 
     but an expression was expected of type 'a 
     The type variable 'a occurs inside ('a -> 'b) -> 'c 

Это работает, если я прохожу -rectypes переводчика:

# let rec f g = g f ;; 
val f : ('a -> 'b) -> 'b as 'a = <fun> 

Но есть способ, чтобы он хорошо набран не давая возможность ocaml ?

Я не знаю, как комментировать код, потому что тип f зависит от типа g, который сам по себе зависит от типа f.

+2

Для того, чтобы отключите «возникшую» ошибку, которую вы видите, используйте опцию 'rectypes' [требуется] (http://programmers.stackexchange.com/a/215867/103181), поэтому она не отображается, вы можете сделать это в соответствии с унификация типа 'ocaml' без' rectypes'. – ely

+0

Вы хотите иметь эту функцию, потому что она вам нужна, или это вопрос любопытства? Если вам это нужно, возможно, есть лучший способ сделать это. – PatJ

+1

@PatJ: Я пытался воспроизвести '(loop [bindings] ... recur [bindings])' Синтаксис Clojure в OCaml с 'let rec loop bindings body = body bindings loop', но если вы знаете' loop'/'recur' в Clojure, он может быть перенесен на OCaml с рекурсивной функцией и аккумулятором вместо передачи функции обратного вызова. TL; DR: нет, мне это не нужно, это был просто эксперимент. – bfontaine

ответ

1

В его нынешнем виде вы не можете напечатать чек, причина объясняется другими ответами.

Однако вы можете получить приближение обертывания параметра функции с полиморфным вариантом:

# let rec f (`F g) = g (`F f);; 
val f: [< `F of [> `F of 'a ] -> 'b ] -> 'b = <fun> 

Результат применения этой функции зависит от поведения его параметра:

# f (`F (fun _ -> 13)); 
-: int = 13 
# f (`F f);; (* infinite recursion *) 
^CInterrupted 
1

Невозможно обойти это без использования -rectypes.

Смежные вопросы