OCaml多态递归错误 [英] OCaml polymorphic recursion errors
问题描述
给出以下类型:
type _ task =
| Success : 'a -> 'a task
| Fail : 'a -> 'a task
| Binding : (('a task -> unit) -> unit) -> 'a task
| AndThen : ('a -> 'b task) * 'a task -> 'b task
| OnError : ('a -> 'b task) * 'a task -> 'b task
type _ stack =
| NoStack : 'a stack
| AndThenStack : ('a -> 'b task) * 'b stack -> 'a stack
| OnErrorStack : ('a -> 'b task) * 'b stack -> 'a stack
type 'a process =
{ root: 'a task
; stack: 'a stack
}
let rec loop : 'a. 'a process -> unit = fun proc ->
match proc.root with
| Success value ->
let rec step = function
| NoStack -> ()
| AndThenStack (callback, rest) -> loop {proc with root = callback value; stack = rest }
| OnErrorStack (_callback, rest) -> step rest <-- ERROR HERE
in
step proc.stack
| Fail value ->
let rec step = function
| NoStack -> ()
| AndThenStack (_callback, rest) -> step rest
| OnErrorStack (callback, rest) -> loop {proc with root = callback value; stack = rest }
in
step proc.stack
| Binding callback -> callback (fun task -> loop {proc with root = task} )
| AndThen (callback, task) -> loop {root = task; stack = AndThenStack (callback, proc.stack)}
| OnError (callback, task) -> loop {root = task; stack = OnErrorStack (callback, proc.stack)}
我从编译器中得到一个错误:
I get an error from the compiler:
错误:此表达式的类型为b#1堆栈 但是应该使用'a stack类型的表达式 类型构造函数b#1会逃避其作用域
Error: This expression has type b#1 stack but an expression was expected of type 'a stack The type constructor b#1 would escape its scope
在这一行代码中:
| Success value ->
let rec step = function
| NoStack -> ()
| AndThenStack (callback, rest) -> loop {proc with root = callback value; stack = rest }
| OnErrorStack (_callback, rest) -> step rest <-- ERROR HERE
in
step proc.stack
花点时间才能解决这个问题,而不会遇到晦涩的错误消息,而不可避免地会通过使用一些帮助程序类型进行纠正,但是我似乎无法弄清楚如何使用帮助程序来解决此问题,或者如果我我试图对我的类型做些愚蠢的事情.
It's taken a while to get this far without running into an obscure error message that is inevitably corrected by using some helper types, but I can't seem to figure out how to correct this issue with a helper, or if I'm attempting to do something silly with my types.
消除此错误的正确方法是什么?
What is the correct way to eliminate this error?
推荐答案
第二个变量需要添加到任务类型定义中,以表示单独的成功和失败值.这是完整的解决方案:
A second variable needed to be added to the task type definition to express separate success and failure values. Here is the complete solution:
type (_,_) task =
| Success : 'a -> ('a,_) task
| Fail : 'x -> (_,'x) task
| Binding : ((('a,'x) task -> unit) -> unit) -> ('a,'x) task
| AndThen : ('a -> ('b,'x) task) * ('a,'x) task -> ('b,'x) task
| OnError : ('x -> ('a,'y) task) * ('a,'x) task -> ('a,'y) task
type (_,_) stack =
| NoStack : (_,_) stack
| AndThenStack : ('a -> ('b,'x) task) * ('b,'x) stack -> ('a,'x) stack
| OnErrorStack : ('x -> ('a,'y) task) * ('a,'y) stack -> ('a,'x) stack
type ('a,'x) process =
{ root: ('a,'x) task
; stack: ('a,'x) stack
}
let rec loop : type a x. (a, x) process -> unit = fun proc ->
match proc.root with
| Success value ->
let rec step : 'x. (a, 'x) stack -> unit = function
| NoStack -> ()
| AndThenStack (callback, rest) -> loop {root = callback value; stack = rest }
| OnErrorStack (_callback, rest) -> step rest
in
step proc.stack
| Fail value ->
let rec step : 'a. ('a, x) stack -> unit = function
| NoStack -> ()
| AndThenStack (_callback, rest) -> step rest
| OnErrorStack (callback, rest) -> loop {root = callback value; stack = rest }
in
step proc.stack
| Binding callback -> callback (fun task -> loop {proc with root = task})
| AndThen (callback, task) -> loop {root = task; stack = AndThenStack (callback, proc.stack)}
| OnError (callback, task) -> loop {root = task; stack = OnErrorStack (callback, proc.stack)}
这篇关于OCaml多态递归错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!