The types below are taken from this question
(* contains an error, later fixed by the OP *)
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
}
I'm relatively new to OCaml, but I've never seen :
syntax used like that before. For example, I've seen polymorphic types defined like this, using the of
syntax
type 'a expr =
| Base of 'a
| Const of bool
| And of 'a expr list
| Or of 'a expr list
| Not of 'a expr
In the original question, It's not obvious to me how the variants are even constructed, since it looks like each one does not accept an argument. Take this simplified example
type 'a stack =
| Foo : int stack
| Bar : string stack
;;
type 'a stack = Foo : int stack | Bar : string stack
Try making an int stack
using Foo
Foo 5;;
Error: The constructor Foo expects 0 argument(s),
but is applied here to 1 argument(s)
However, without an argument
Foo;;
- : int stack = Foo
Ok, but where's the int
? How to store data in this type?
In the OP's program below, he/she is matching on the types "normally", eg Success value -> ...
or Fail value -> ...
. Again, how is this value constructed if the variant constructor doesn't accept an argument?
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)}
Can someone help me filling in my knowledge gap?
Foo : int -> int stack
or evenFoo : int * int stack -> int stack
). – Bustosof
form? – Equatorial