I'm studying monad composition. While I already understand how to compose, say, Async and Result as performed here I'm struggling in composing the Continuation Monad and the State Monad.
Starting from a basic State Monad implementation and aState-based-Stack for testing purposes:
type State<'State,'Value> = State of ('State -> 'Value * 'State)
module State =
let runS (State f) state = f state
let returnS x =
let run state =
x, state
State run
let bindS f xS =
let run state =
let x, newState = runS xS state
runS (f x) newState
State run
let getS =
let run state = state, state
State run
let putS newState =
let run _ = (), newState
State run
type StateBuilder()=
member __.Return(x) = returnS x
member __.Bind(xS,f) = bindS f xS
let state = new StateBuilder()
module Stack =
open State
type Stack<'a> = Stack of 'a list
let popStack (Stack contents) =
match contents with
| [] -> failwith "Stack underflow"
| head::tail ->
head, (Stack tail)
let pushStack newTop (Stack contents) =
Stack (newTop::contents)
let emptyStack = Stack []
let getValue stackM =
runS stackM emptyStack |> fst
let pop() = state {
let! stack = getS
let top, remainingStack = popStack stack
do! putS remainingStack
return top }
let push newTop = state {
let! stack = getS
let newStack = pushStack newTop stack
do! putS newStack
return () }
Then having also a basic implementation of a Continuation Monad :
type Cont<'T,'r> = (('T -> 'r) -> 'r)
module Continuation =
let returnCont x = (fun k -> k x)
let bindCont f m = (fun k -> m (fun a -> f a k))
let delayCont f = (fun k -> f () k)
let runCont (c:Cont<_,_>) cont = c cont
let callcc (f: ('T -> Cont<'b,'r>) -> Cont<'T,'r>) : Cont<'T,'r> =
fun cont -> runCont (f (fun a -> (fun _ -> cont a))) cont
type ContinuationBuilder() =
member __.Return(x) = returnCont x
member __.ReturnFrom(x) = x
member __.Bind(m,f) = bindCont f m
member __.Delay(f) = delayCont f
member this.Zero () = this.Return ()
let cont = new ContinuationBuilder()
I'm trying to compose it like this :
module StateK =
open Continuation
let runSK (State f) state = cont { return f state }
let returnSK x = x |> State.returnS |> returnCont
let bindSK f xSK = cont {
let! xS = xSK
return (State.bindS f xS) }
let getSK k =
let run state = state, state
State run |> k
let putSK newState = cont {
let run _ = (), newState
return State run }
type StateContinuationBuilder() =
member __.Return(x) = returnSK x
member __.ReturnFrom(x) = x
member __.Bind(m,f) = bindSK f m
member this.Zero () = this.Return ()
let stateK = new StateContinuationBuilder()
While this compiles and seems right (as far as a mechanically-following-steps-composition goes) I'm not able to implement a StateK-based-Stack.
So far I have this, but it is totally wrong:
module StackCont =
open StateK
type Stack<'a> = Stack of 'a list
let popStack (Stack contents) = stateK {
match contents with
| [] -> return failwith "Stack underflow"
| head::tail ->
return head, (Stack tail) }
let pushStack newTop (Stack contents) = stateK {
return Stack (newTop::contents) }
let emptyStack = Stack []
let getValue stackM = stateK {
return runSK stackM emptyStack |> fst }
let pop() = stateK {
let! stack = getSK
let! top, remainingStack = popStack stack
do! putSK remainingStack
return top }
let push newTop = stateK {
let! stack = getSK
let! newStack = pushStack newTop stack
do! putSK newStack
return () }
Some help to understand why and how is more than welcome.
If there is some reading material you can point to, it will also work.
********* EDIT after AMieres comment **************
New bindSK implementation trying to keep signatures right.
type StateK<'State,'Value,'r> = Cont<State<'State,'Value>,'r>
module StateK =
let returnSK x : StateK<'s,'a,'r> = x |> State.returnS |> Continuation.returnCont
let bindSK (f : 'a -> StateK<'s,'b,'r>)
(m : StateK<'s,'a,'r>) : StateK<'s,'b,'r> =
(fun cont ->
m (fun (State xS) ->
let run state =
let x, newState = xS state
(f x) (fun (State k) -> k newState)
cont (State run)))
Nevertheless, the type 'r has been constrained to be 'b * 's
I have tried to remove the constraint but I haven't yet been able to do it
I have not been able to solve it either.
I can only give you a tip that may help you understand it better. Replace generic types for regular types, for instance instead of:
let bindSK (f : 'a -> StateK<'s,'b,'r>)
(m : StateK<'s,'a,'r>) : StateK<'s,'b,'r> =
(fun cont ->
m (fun (State xS) ->
let run state =
let x, newState = xS state
(f x) (fun (State k) -> k newState)
cont (State run)))
replace 's with string, 'a with int, 'b with char and 'r with float
let bindSK (f : int -> StateK<string,char,float>)
(m : StateK<string,int,float>) : StateK<string,char,float> =
(fun cont ->
m (fun (State xS) ->
let run state =
let x, newState = xS state
(f x) (fun (State k) -> k newState)
cont (State run)))
that way is easier to see that
k is string -> char * string
so k newState is char * string
(f x) is (State<string,char> -> float) -> float
and m is (State<string,int> -> float) -> float
so they are not compatible.
I read more and it comes out that the correct type for a "ContinuousState" is 's -> Cont<'a * 's, 'r>
So I re-implemented the StateK monad with this signatures and all flew naturally.
Here is the code (I added mapSK and applySK for completeness):
type Cont<'T,'r> = (('T -> 'r) -> 'r)
let returnCont x = (fun k -> k x)
let bindCont f m = (fun k -> m (fun a -> f a k))
let delayCont f = (fun k -> f () k)
type ContinuationBuilder() =
member __.Return(x) = returnCont x
member __.ReturnFrom(x) = x
member __.Bind(m,f) = bindCont f m
member __.Delay(f) = delayCont f
member this.Zero () = this.Return ()
let cont = new ContinuationBuilder()
type StateK<'State,'Value,'r> = StateK of ('State -> Cont<'Value * 'State, 'r>)
module StateK =
let returnSK x =
let run state = cont {
return x, state
}
StateK run
let runSK (StateK fSK : StateK<'s,'a,'r>) (state : 's) : Cont<'a * 's, _> = cont {
return! fSK state }
let mapSK (f : 'a -> 'b) (m : StateK<'s,'a,'r>) : StateK<'s,'b,'r> =
let run state = cont {
let! x, newState = runSK m state
return f x, newState }
StateK run
let bindSK (f : 'a -> StateK<'s,'b,'r>) (xSK : StateK<'s,'a,'r>) : (StateK<'s,'b,'r>) =
let run state = cont {
let! x, newState = runSK xSK state
return! runSK (f x) newState }
StateK run
let applySK (fS : StateK<'s, 'a -> 'b, 'r>) (xSK : StateK<'s,'a,'r>) : StateK<'s,'b,'r> =
let run state = cont {
let! f, s1 = runSK fS state
let! x, s2 = runSK xSK s1
return f x, s2 }
StateK run
let getSK =
let run state = cont { return state, state }
StateK run
let putSK newState =
let run _ = cont { return (), newState }
StateK run
type StateKBuilder() =
member __.Return(x) = returnSK x
member __.ReturnFrom (x) = x
member __.Bind(xS,f) = bindSK f xS
member this.Zero() = this.Return ()
let stateK = new StateKBuilder()
module StackCont =
open StateK
type Stack<'a> = Stack of 'a list
let popStack (Stack contents) =
match contents with
| [] -> failwith "Stack underflow"
| head::tail ->
head, (Stack tail)
let pushStack newTop (Stack contents) =
Stack (newTop::contents)
let emptyStack = Stack []
let getValueSK stackM = cont {
let! f = runSK stackM emptyStack
return f |> fst }
let pop() = stateK {
let! stack = getSK
let top, remainingStack = popStack stack
do! putSK remainingStack
return top }
let push newTop = stateK {
let! stack = getSK
let newStack = pushStack newTop stack
do! putSK newStack
return () }
open StateK
open StackCont
let helloWorldSK = (fun () -> stateK {
do! push "world"
do! push "hello"
let! top1 = pop()
let! top2 = pop()
let combined = top1 + " " + top2
return combined
})
let helloWorld = getValueSK (helloWorldSK ()) id
printfn "%s" helloWorld
I gave it another shot and came around with this, as far as I can tell it works and it is effectively a Cont · State:
type State<'State,'Value> = State of ('State -> 'Value * 'State)
type StateK<'s,'T> = ((State<'s,'T> -> 'T * 's) -> 'T * 's)
let returnCont x : StateK<'s,'a> = (fun k -> k x)
let returnSK x =
let run state =
x, state
State run |> returnCont
let runSK (f : ((State<'s,'b> -> 'b * 's) -> 'b * 's)) state = f (fun (State xS) -> xS state)
let bindSK (f : 'a -> StateK<'s,'b>) (xS :StateK<'s,'a>) : StateK<'s,'b> =
let run state =
let x, newState = runSK xS state
runSK (f x) newState
returnCont (State run) // is this right? as far as I cant tell the previous (next?) continuation is encapsulated on run so this is only so the return type conforms with what is expected of a bind
let getSK k =
let run state = state, state
State run |> k
let putSK newState =
let run _ = (), newState
State run |> returnCont
type StateKBuilder()=
member __.Return(x) = returnSK x
member __.Bind(xS,f) = bindSK f xS
let stateK = new StateKBuilder()
type Stack<'a> = Stack of 'a list
let popStack (Stack contents) =
match contents with
| [] -> failwith "Stack underflow"
| head::tail ->
head, (Stack tail)
let pushStack newTop (Stack contents) =
Stack (newTop::contents)
let emptyStack = Stack []
let getValueS stackM =
runSK stackM emptyStack |> fst
let pop () = stateK {
let! stack = getSK
let top, remainingStack = popStack stack
do! putSK remainingStack
return top }
let push newTop = stateK {
let! stack = getSK
let newStack = pushStack newTop stack
do! putSK newStack
return () }
let helloWorldSK = (fun k -> stateK {
do! push "world"
do! push "hello"
let! top1 = pop()
let! top2 = pop()
let combined = top1 + " " + top2
return combined
})
let helloWorld = getValueS (helloWorldSK id)
printfn "%s" helloWorld
Related
What is the right way to append items to a list inside a recursive function?
let () =
let rec main m l acc =
if (acc = 3) then
acc
else
if (m = 1) then
l := 1 :: !l
main (m - 1) l
else if (m = 2) then
l := 2 :: !l
main (m - 1) l
else
l := m :: !l
main (m - 1) l
in l = ref []
let main 10 l 0
List.iter (fun l -> List.iter print_int l) l
another Example:
let () =
let rec main m =
if (m = 3) then m
else
l := m :: !l;
main (m + 1) l
in l = ref []
let main 0 l
List.iter (fun l -> List.iter print_int l) l
I want to append a value to a list inside a function and then print the elements of the list.
If you want to print [1;2;...;10]:
let () =
let rec main m l =
if (m = 0) then
!l
else begin
l := m :: !l;
main (m - 1) l
end
in
let l = ref [] in
List.iter print_int (main 10 l); print_newline();;
or better without ref
let () =
let rec main m l =
if (m = 0) then
l
else
main (m - 1) (m::l)
in
List.iter print_int (main 10 []); print_newline();;
but I am not sure of what you want to do...
What you mean by "the right way" is not quite clear. The functional "right way" would be not to use references. The efficiency "right way" would be to prepend rather than to append.
Another direct way to build a list inspired from user4624500's answer could be:
let rec f = function
| 0 -> [0]
| n -> n :: f (n-1)
(note: that's not tail recursive, and would uglily fail with negative numbers...)
Then the following expression calls the previous function to build the list and then print the result (adding newlines for readability purposes):
let my_list = f 10 in
List.iter (fun n -> print_int n; print_newline ()) my_list
I wrote the following code in SML with the NJ Compiler:
fun all_answers (f, xs) =
let
fun aux(accu, xs_left) =
case xs of
[] => SOME accu
| x::xs' => case f(x) of
NONE => NONE
| SOME y => aux(accu#y, xs')
in
aux([], xs)
end
It works well for this tests:
val testAll1 = all_answers ((fn x => if x = 1 then SOME [x] else NONE), []) = SOME []
val testAll2 = all_answers ((fn x => if x = 1 then SOME [x] else NONE), [2,3,4,5,6,7]) = NONE
However, something weird happens with this test:
val testAll3 = all_answers ((fn x => if x = 1 then SOME [x] else NONE), [1]) = SOME [1]
After running the program, the terminal goes on forever.
I defined the tail recursion and used the pattern-match with xs' to reach the tail.
Moreover, I defined the base case to end the recursion so that if xs is [] then the auxiliary function returns SOME accumulator
Can anybody help me?
Thanks in advance.
As #kopecs pointed out, this is caused by case xs of when you want case xs_left of.
Here is a cleaned up (whitespace, naming) version of your function:
fun all_answers (f, ys) =
let
fun aux (accu, xs) =
case xs of
[] => SOME accu
| x::xs' => case f x of
NONE => NONE
| SOME y => aux (accu#y, xs)
in
aux ([], ys)
end
There are at least two things you could do to simplify the way this function is made. (1) Perform the case xs of inside the function pattern rather than in a nested case-of. (2) Remove the inner aux function and simply do the recursion in the outer function, at the expense of some tail-recursion
The first simplification might look like:
fun all_answers2 (f, ys) =
let
fun aux (accu, []) = SOME accu
| aux (accu, x::xs) =
case f x of
NONE => NONE
| SOME y => aux (accu#y, xs)
in
aux ([], ys)
end
And the second might look like:
fun all_answers' (f, []) = SOME []
| all_answers' (f, x::xs) =
case f x of
NONE => NONE
| SOME ys => case all_answers' (f, xs) of
NONE => NONE
| SOME result => SOME (ys # result)
This shows a pattern: Whenever you have
case f x of
NONE => NONE
| SOME y => case g y of
NONE => NONE
| SOME z => ...
then you have a programming pattern that could be abstracted out with a function.
There is already a standard library function that is made for this called Option.map, so you could write:
fun all_answers3 (f, ys) =
let
fun aux (accu, []) = SOME accu
| aux (accu, x::xs) =
Option.map (fn y => aux (accu#y, xs))
(f x)
in
aux ([], ys)
end
Try and play around with this function in the REPL:
- Option.map (fn y => y + 2) NONE;
> val it = NONE : int option
- Option.map (fn y => y + 2) (SOME 2);
> val it = SOME 4 : int option
Taking this in another direction, rather than an inner function:
(* Alternative to Option.map: *)
fun for NONE _ = NONE
| for (SOME x) f = f x
(* Equivalent to Option.mapPartial with "flipped" arguments: *)
fun for opt f = Option.mapPartial f opt
fun all_answers'' (f, []) = SOME []
| all_answers'' (f, x::xs) =
for (f x) (fn ys =>
for (all_answers'' (f, xs)) (fn result =>
SOME (ys # result)))
This style is more Haskell-like because it follows a monadic design pattern.
I write a ocaml program that parse an arithmetic expression by parser combinator.
type 'a parser = char list -> ('a * (char list)) list
let return (x: 'a): 'a parser = fun input -> [x, input]
let fail: 'a parser = fun _ -> []
let ( >>= ) (p: 'a parser) (f : 'a -> 'b parser): 'b parser =
fun input -> List.map (fun (x, i) -> f x i) (p input) |> List.flatten
let ( ||| ) (p: 'a parser) (q: 'a parser) =
fun input -> (p input) # (q input)
let token: (char parser) = function
| x::xs -> [x, xs]
| [] -> []
let char(c: char): (char parser) =
token >>= fun x ->
if x = c then return x else fail
let digit: (char parser) =
token >>= fun x ->
if x >= '0' && x <= '9' then return x else fail
let rec many(p: 'a parser): 'a list parser =
(p >>= fun x ->
many p >>= fun xs ->
(return (x::xs)))
||| (return [])
let number =
many digit >>= fun x ->
return (List.fold_left (fun l r -> l * 10 + (int_of_char r - int_of_char '0')) 0 x)
type expr = Add of (expr * expr)
| Sub of (expr * expr)
| Mul of (expr * expr)
| Div of (expr * expr)
| Neg of expr
The code above works well.
let rec expression: expr parser =
term >>= fun l ->
(char '+' ||| char '-') >>= fun op ->
term >>= fun r ->
if op = '+' then return (Add (l, r)) else return (Sub (l, r))
and term: expr parser =
factor >>= fun l ->
(char '*' ||| char '/') >>= fun op ->
factor >>= fun r ->
if op = '*' then return (Mul (l, r)) else return (Div (l, r))
and factor: expr parser =
expression
||| (char '(' >>= fun _ ->
expression >>= fun e ->
char ')' >>= fun _ ->
return e)
||| (char '-' >>= fun _ ->
factor >>= fun e ->
return (Neg e))
But there is an error in this piece of code
Error: This kind of expression is not allowed as right-hand side of `let rec'
This page(link) says:
"the compiler only allows three possible constructs to show up on the righthand side of a let rec: a function definition, a constructor, or the lazy keyword."
I think type parser is a function instead of a value, why this happened?
"Function definition" means a literan fun x -> construct. Functional languages consider partial function applications like
factor >>= fun l -> ...
redexes, not literal values, which means a strict language has to evaluate them immediately when they appear on the RHS of a simple variable binding, like
term = factor >>= fun l -> ...
Since, in general, eagerly evaluating the RHS of a recursive definition produces an infinite loop, strict languages generally either ban the construct or require the binding to be marked explicitly lazy.
The right hand side should be "function definition" not just a function. Function definition is a syntactic construct, of the form fun -> or function ..., including syntactic sugar for let f x .... A more correct wording is in sections 6.7.1 and 7.3 of the manual.
I implemented a non-in-place version of selection sort in OCaml.
let sort compare_fun l =
let rec find_min l' min_l origin_l =
match l' with
| [] ->
if min_l = [] then (min_l, l')
else
let min = List.hd min_l
in
(min_l, List.filter (fun x -> if x != min then true else false) origin_l)
| x::tl ->
if min_l = [] then
find_min tl [x] origin_l
else
let c = compare_fun (List.hd min_l) x
in
if c = 1 then
find_min tl [x] origin_l
else if c = 0 then
find_min tl (min_l # [x]) origin_l
else
find_min tl min_l origin_l
in
let rec insert_min l' new_l =
match l' with
| [] -> new_l
| _ ->
let (min_l, rest) = find_min l' [] l'
in
insert_min rest (new_l # min_l)
in
insert_min l [];;
My idea is that in a list, every time I find the list of minimum items (in case of duplicate values) and add this min list to the result list, then redo the finding_min in the rest of the list.
I use List.filter to filter out the min_list, so the resulting list will be the list for next find_min.
I find my implementation is quite complicated, and far more complicated than the Java in-place version of selection sort.
Any suggestions to improve it?
Edit: Here's a much better implementation: http://rosettacode.org/wiki/Sorting_algorithms/Selection_sort#OCaml
here's my own crappier implementation
(* partial function - bad habit, don't do this. *)
let smallest (x::xs) = List.fold_right (fun e acc -> min e acc) xs x
let remove l y =
let rec loop acc = function
| [] -> raise Not_found
| x::xs -> if y = x then (List.rev acc) # xs else loop (x::acc) xs
in loop [] l
let selection_sort =
let rec loop acc = function
| [] -> List.rev acc
| xs ->
let small = smallest xs in
let rest = remove xs small in
loop (small::acc) rest
in loop []
I think I want it be be of type 'a list * 'a list -> 'a list .
intersection should return the intersection of two lists
sample input and output:
intersection ([1],[1]);
[1]
intersection ([1,2,3],[1,2]);
[1,2]
intersection ([[2,3],[1,2],[2,3]], [[1],[2,3]]);
[[2,3]]
my function:
fun intersection (l1, l2) = let
fun intersection_acc (acc, [], h::t) = []
| intersection_acc (acc, h::t, []) = []
| intersection_acc (acc, h::t, h2::t2) = if in_list (h, l2)
then intersection_acc (h::acc, t, l2)
else intersection_acc (acc, t, l2)
in intersection_acc ([], l1, l2)
end
I don't think in_list is the problem, but that looks like this:
fun in_list (x, []) = false
| in_list (x, y::r) = if x = y
then true
else in_list (x, r);
My guess is that you botched the base case in your accumulator function
intersection_acc (acc, h::t, []) = []
it should probably return something depending on acc:
intersection_acc (acc, h::t, []) = acc
The reason the 'b list shows up is because intersection will always return the empty list []. Since you don't use that empty list the compiler needs to be conservative and say that the list could be of any type.
In any case, your function seems to be fundamentally more confused. You actually want to do something like
result = []
for each item in list1:
if item in list2:
add item to result
return result
Translating this imperative code to a recursive function with an accumulator parameter:
fun go(acc, []) = acc
| go(acc, x::xs) =
if x in list2 then
go(x::acc, xs)
else
go(acc, xs)
For the full function:
fun intersect(list1, list2) = let
fun go(acc, []) = acc
| go(acc, x::xs) =
if x in list2 then
go(x::acc, xs)
else
go(acc, xs)
in go([], list1)