Stackless trampoline Monad/Computation Expression - f#

I am working on a functional programming language of my own design and I stumbled on a problem that is beyond my skills to solve. I would like to know if anyone has any advice on how to solve it or a reason for why it is impossible.
The code below is an overview of a solution that is not the ideal but a compromise.
This problem is at the heart of the runtime system I am currently using. Instead of relying on the .Net stack I am using a monad to perform operations on a trampoline. This should help with step through debugging and allow for users to not have to worry about stack space. Here is a simplified version of the monad I am currently using.
type 't StackFree =
|Return of 't //Return a value
|StackPush of ('t->'t StackFree)*'t StackFree //Pushes a return handler onto the "Stack"
|Continuation of (unit->'t StackFree) //Perform a simple opperation
type StackFreeMonad() =
member this.Delay(fn) =
Continuation(fn)
member this.Bind(expr,fn) =
StackPush(fn,expr)
member this.Return(value) =
Return(value)
member this.ReturnFrom(x) =x
let stackfree = StackFreeMonad()
This was not the original design but it was the best I could get to work with F# computation expressions in an ideal world the above computation expression would work on this type.
type 't Running =
|Result of 't
|Step of (unit->'t Running)
So in order to convert a StackFree into a Running type I have to use this conversion function
//this method loops through the StackFree structure finding the next computation and managing a pseudo stack with a list.
let prepareStackFree<'t> :'t StackFree->'t Running =
let rec inner stack stackFree =
Step(fun ()->
match stackFree with
//takes the return values and passes it to the next function on the "Stack"
|Return(value)->
match stack with
|[]->Result(value)
|x::xs -> inner xs (x value)
//pushes a new value on the the "Stack"
|StackPush(ret,next) ->
inner (ret::stack) next
//performs a single step
|Continuation(fn)->
inner stack (fn()))
inner []
Here is a brief example of the two types in action.
let run<'t> :'t StackFree->'t =
let rec inner = function
|Step(x)-> inner (x())
|Result(x)-> x
stackFreeToRunning>>inner
//silly function to recompute an intiger value using recursion
let rec recompute number = stackfree {
if number = 0 then return 0
else
let! next = recompute (number-1)
return next+1
}
let stackFreeValue = recompute 100000
let result = run stackFreeValue
do printfn "%i" result
I have spent several hours trying to get a Computation Expression that works directly on the Running type and cutting out the middleman StackFree. However I cannot figure out how to do it. At this point I am seriously considering the possibility that a solution to this problem is impossible. However I cannot figure out the reason that it is impossible.
I have gotten close a few times but the resulting solutions ended up using the stack in some confusing way.
Is it possible to have a computation expression that operates on the Running type without utilizing the .Net stack? If this is not possible why is it not possible. There must be some simple mathematical reasoning that I am missing.
NB: These are not the actual types I am using they are simplified for this questions the real ones keep track of scope and position in the script. Furthermore I am aware of the serious performance cost of this type of abstraction
Edit: Here is another way to approach the problem. This implementation is flawed because it uses the stack. Is there anyway to get the exact behavior below without using the stack?
type RunningMonad() =
member this.Delay(fn) =
Step(fun ()->fn ())
member this.Bind(m, fn) =
Step(fun ()->
match m with
|Result(value)-> fn value
//Here is the problem
|Step(next)-> this.Bind(next(),fn))
member this.Return(v) =
Result(v)
member this.ReturnFrom(x) = x
The bind implementation in the above computation expression creates a function that calls another function. So as you go deeper and call bind more and more you have to chase a bunch of function calls and then eventually you hit a stackoverflow exception.
Edit2: Clarity.

Better late than never!
This is addressed in section 4 of Stackless Scala with Free Monads. Bjarnason tackles the problem by adding a new constructor to the Trampoline datatype, representing a subroutine call to another trampoline. He keeps this new constructor private, in order to ensure that you can't build left-nested Binds (which would overflow the stack when executing the trampoline).
I am by no means an F#er, but I'll muddle through. In WishF#ul, an imaginary dialect of F# which I just made up, you can express the new existentially quantified constructor directly:
type Tram<'a> =
| Done of 'a
| Step of (unit -> Tram<'a>)
| Call<'x> of Tram<'x> * ('x -> Tram<'a>) // don't export this
type TramMonad() =
member this.Return(x) = Done(x)
member this.Bind(ma, f) = match ma with
| Call(mx, k) -> Call(mx, fun x -> this.Bind(k(x), f))
| _ -> Call(ma, f)
// i confess to not quite understanding what your Delay and ReturnFrom methods are for
let tram = new TramMonad()
let rec runTram t =
let next mx f = match mx with
| Done(x) -> f x
| Step(k) -> Step(fun () -> tram.Bind(k(), f))
| Call(my, g) -> tram.Bind(my, fun x -> tram.Bind(g x, f))
match t with
| Done(x) -> x
| Step(k) -> runTram(k())
| Call(mx, f) -> runTram(next mx f)
Note that all of the recursive calls to runTram are in tail position. It takes a bit of puzzling, but you can convince yourself that Bind won't construct a deeply-nested continuation, so runT will always operate in O(1) stack space.
Sadly we're working in F#, not WishF#ul, so we have to resort to an object-oriented encoding of the existential type in the Call constructor. Here goes...
module rec Trampoline =
type Call<'a> =
abstract member Rebind<'b> : ('a -> Tram<'b>) -> Tram<'b>
abstract member Next : unit -> Tram<'a>
type Tram<'a> =
| Done of 'a
| Step of (unit -> Tram<'a>)
| Call of Call<'a>
type TramMonad() =
member this.Return(x) = Done(x)
member this.Bind(ma, f) =
match ma with
| Call(aCall) -> aCall.Rebind(f)
| _ -> call ma f
let tram = new TramMonad()
let rec call<'a, 'x>(mx : Tram<'x>) (f : 'x -> Tram<'a>) : Tram<'a> = Call {
new Call<'a> with
member this.Rebind<'b>(g : 'a -> Tram<'b>) : Tram<'b> =
call<'b, 'x> mx (fun x -> tram.Bind(f x, g) : Tram<'b>)
member this.Next() =
match mx with
| Done(x) -> f x
| Step(k) -> Step(fun () -> tram.Bind(k(), f))
| Call(aCall) -> aCall.Rebind(f)
}
let rec runTram t =
match t with
| Done(x) -> x
| Step(k) -> runTram(k())
| Call(aCall) -> runTram(aCall.Next())
I recommend reading the whole paper, which goes on to generalise this stackless construction to any free monad, not just trampolines (which are Free (Unit -> _)). Phil Freeman's Stack Safety for Free builds on this work, generalising the trampoline paper's free monad to a free monad transformer.

Related

How do I compose a list of functions?

If I have a type named Person, and list of functions, for example...
let checks = [checkAge; checkWeight; checkHeight]
...where each function is of the type (Person -> bool), and I want to do the equivalent of...
checkAge >> checkWeight >> checkHeight
...but I don't know in advance what functions are in the list, how would I do it?
I tried the following...
checks |> List.reduce (>>)
...but this gives the following error...
error FS0001: Type mismatch. Expecting a
(Person -> bool) -> (Person -> bool) -> Person -> bool
but given a
(Person -> bool) -> (bool -> 'a) -> Person -> 'a
The type 'Person' does not match the type 'bool'
What am I doing wrong?
It looks like Railway oriented programming would be a good fit here.
If you choose to go this route, you basically have two options.
You can either go all in, or the quick route.
Quick route
You rewrite your validation functions to take a Person option instead of just plain Person.
let validAge (record:Record option) =
match record with
| Some rec when rec.Age < 65 && rec.Age > 18 -> record
| None -> None
Now you should be able to easily chain your function.
checks |> List.reduce (>>)
All in
Alternatively, if you are lazy and don't want to match .. with in every validation function, you can write some more code.
(samples taken from [1])
First there's a bit of setup to do.
We'll define a special return type, so we can get meaningful error messages.
type Result<'TSuccess,'TFailure> =
| Success of 'TSuccess
| Failure of 'TFailure
A bind function, to bind the validations together
let bind switchFunction =
function
| Success s -> switchFunction s
| Failure f -> Failure f
You'll have to rewrite your validation functions as well.
let validAge (record:Record) =
if record.Age < 65 && record.Age > 18 then Success input
else Failure "Not the right age bracket"
Now combine with
checks |> List.reduce (fun acc elem -> acc >> bind elem)
Either way, check out the original article.
There's much more there you might be able to use :)
Edit: I just noticed that I was too slow in writing this answer once again.
Besides, I think Helge explained the concetp better than I did as well.
You may somehow have stumbled upon a dreaded concept. Apperently its the Voldemort (dont say his name!) of functional programming.
With no further ado lets walk right into the code:
type Person =
{ Name : string
Age : int
Weight : int
Height : int }
type Result =
| Ok of Person
| Fail
let bind f m =
match m with
| Ok p -> f p
| _ -> Fail
let (>=>) f1 f2 = f1 >> (bind f2)
let checkAge p =
if p.Age > 18 then Ok(p)
else Fail
let checkWeight p =
if p.Weight < 80 then Ok(p)
else Fail
let checkHeight p =
if p.Height > 150 then Ok(p)
else Fail
let checks = [ checkAge; checkWeight; checkHeight ]
let allcheckfunc = checks |> List.reduce (>=>)
let combinedChecks =
checkAge
>=> checkWeight
>=> checkHeight
let p1 =
{ Name = "p1"
Age = 10
Weight = 20
Height = 110 }
let p2 =
{ Name = "p2"
Age = 19
Weight = 65
Height = 180 }
allcheckfunc p1
combinedChecks p1
allcheckfunc p2
combineChecks p2
At this point I could throw around a lot of weirdo lingo (not really true, I couldnt...), but lets just look at what I have done.
I dropped your return value of bool and went for another type (Result) with either (mark that keyword!) Ok or Fail.
Then made a helper (bind) to wrap and unwrapp stuff from that Result-type.
And a new operator (>=>) to combine the stuff in reduce.
Mind that the first check-function to Fail will shortcut the entire chain and more or less immediately (not calling the other functions) return Fail. In addition you will not know where in this chain it did Fail or which functions ahead of any Fail did actually Ok.
There are methods to also accumulate the errors as you go along, so that you get get a feedback of type: "the checkAge returned Fail, but the others was great success"
The code is mostly stolen from here: http://fsharpforfunandprofit.com/posts/recipe-part2/
And you may want to read about the entire website of Wlaschin and even a lot more to get into the finer and harder details if wanted.
Good luck on your journey to the upper floors of the Ivory Tower. ;-)
Footnote: This is called an Either-monad usually. Its not entirely finished and what not in the above code, but never mind... I think it will work in your case...
The >> operator is useful if you have functions that perform some transformation. For example, if you had a list of functions Person -> Person that turn one person into another.
In your case, it seems that you have functions Person -> bool and you want to build a composed function that returns true if all functions return true.
Using List.reduce you can write:
checks|> List.reduce (fun f g -> (fun p -> f p && g p))
Perhaps an easier option is to just write a function that takes a person and uses List.forall:
let checkAll checks person = checks |> List.forall (fun f -> f person)

Memoize a function of type () -> 'a

This memoize function fails on any functions of type () -> 'a at runtime with a Null-Argument-Exception.
let memoize f =
let cache = System.Collections.Generic.Dictionary()
fun x ->
if cache.ContainsKey(x) then
cache.[x]
else
let res = f x
cache.[x] <- res
res
Is there a way to write a memoize function that also works for a () -> 'a ?
(My only alternative for now is using a Lazy type. calling x.Force() to get the value.)
The reason why the function fails is that F# represents unit () using null of type unit. The dictionary does not allow taking null values as keys and so it fails.
In your specific case, there is not much point in memoizing function of type unit -> 'a (because it is better to use lazy for this), but there are other cases where this would be an issue - for example None is also represented by null so this fails too:
let f : int option -> int = memoize (fun a -> defaultArg a 42)
f None
The easy way to fix this is to wrap the key in another data type to make sure it is never null:
type Key<'K> = K of 'K
Then you can just wrap the key with the K constructor and everything will work nicely:
let memoize f =
let cache = System.Collections.Generic.Dictionary()
fun x ->
if cache.ContainsKey(K x) then
cache.[K x]
else
let res = f x
cache.[K x] <- res
res
I just found that the last memoize function on the same website using Map instead of Dictionary works for 'a Option -> 'b and () -> 'a too:
let memoize1 f =
let cache = ref Map.empty
fun x ->
match cache.Value.TryFind(x) with
| Some res -> res
| None ->
let res = f x
cache.Value <- cache.Value.Add(x, res)
res
Memoization having a pure function (not just of type unit -> 'a, but any other too) as a lookup key is impossible because functions in general do not have equality comparer for the reason.
It may seem that for this specific type of function unit -> 'a it would be possible coming up with a custom equality comparer. But the only approach for implementing such comparer beyond extremes (reflection, IL, etc.) would be invoking the lookup function as f1 = f2 iff f1() = f2(), which apparently nullifies any performance improvement expected from memoization.
So, perhaps, as it was already noted, for this case optimizations should be built around lazy pattern, but not memoization one.
UPDATE: Indeed, after second look at the question all talking above about functions missing equality comparer is correct, but not applicable, because memoization happens within each function's individual cache from the closure. On the other side, for this specific kind of functions with signature unit->'a, i.e. at most single value of argument, using Dictionary with most one entry is an overkill. The following similarly stateful, but simpler implementation with just one memoized value will do:
let memoize2 f =
let notFilled = ref true
let cache = ref Unchecked.defaultof<'a>
fun () ->
if !notFilled then
cache := f ()
notFilled := false
!cache
used as let foo = memoize2(fun () -> ...heavy on time and/or space calculation...)
with first use foo() performing and storing the result of calculation and all successive foo() just reusing the stored value.
Solution with mutable dictionary and single dictionary lookup call:
let memoize1 f =
// printfn "Dictionary"
let cache = System.Collections.Generic.Dictionary()
fun x ->
let result, value = cache.TryGetValue(x)
match result with
| true -> value
| false ->
// printfn "f x"
let res = f x
cache.Add(x, res)
res

How to implement delay in the maybe computation builder?

Here is what I have so far:
type Maybe<'a> = option<'a>
let succeed x = Some(x)
let fail = None
let bind rest p =
match p with
| None -> fail
| Some r -> rest r
let rec whileLoop cond body =
if cond() then
match body() with
| Some() ->
whileLoop cond body
| None ->
fail
else
succeed()
let forLoop (xs : 'T seq) f =
using (xs.GetEnumerator()) (fun it ->
whileLoop
(fun () -> it.MoveNext())
(fun () -> it.Current |> f)
)
whileLoop works fine to support for loops, but I don't see how to get while loops supported. Part of the problem is that the translation of while loops uses delay, which I could not figure out in this case. The obvious implementation below is probably wrong, as it does not delay the computation, but runs it instead!
let delay f = f()
Not having delay also hinders try...with and try...finally.
There are actually two different ways of implementing continuation builders in F#. One is to represent delayed computations using the monadic type (if it supports some way of representing delayed computations, like Async<'T> or the unit -> option<'T> type as shown by kkm.
However, you can also use the flexibility of F# computation expressions and use a different type as a return value of Delay. Then you need to modify the Combine operation accordingly and also implement Run member, but it all works out quite nicely:
type OptionBuilder() =
member x.Bind(v, f) = Option.bind f v
member x.Return(v) = Some v
member x.Zero() = Some ()
member x.Combine(v, f:unit -> _) = Option.bind f v
member x.Delay(f : unit -> 'T) = f
member x.Run(f) = f()
member x.While(cond, f) =
if cond() then x.Bind(f(), fun _ -> x.While(cond, f))
else x.Zero()
let maybe = OptionBuilder()
The trick is that F# compiler uses Delay when you have a computation that needs to be delayed - that is: 1) to wrap the whole computation, 2) when you sequentially compose computations, e.g. using if inside the computation and 3) to delay bodies of while or for.
In the above definition, the Delay member returns unit -> M<'a> instead of M<'a>, but that's perfectly fine because Combine and While take unit -> M<'a> as their second argument. Moreover, by adding Run that evaluates the function, the result of maybe { .. } block (a delayed function) is evaluated, because the whole block is passed to Run:
// As usual, the type of 'res' is 'Option<int>'
let res = maybe {
// The whole body is passed to `Delay` and then to `Run`
let! a = Some 3
let b = ref 0
while !b < 10 do
let! n = Some () // This body will be delayed & passed to While
incr b
if a = 3 then printfn "got 3"
else printfn "got something else"
// Code following `if` is delayed and passed to Combine
return a }
This is a way to define computation builder for non-delayed types that is most likely more efficient than wrapping type inside a function (as in kkm's solution) and it does not require defining a special delayed version of the type.
Note that this problem does not happen in e.g. Haskell, because that is a lazy language, so it does not need to delay computations explicitly. I think that the F# translation is quite elegant as it allows dealing with both types that are delayed (using Delay that returns M<'a>) and types that represent just an immediate result (using Delay that returns a function & Run).
According to monadic identities, your delay should always be equivalent to
let delay f = bind (return ()) f
Since
val bind : M<'T> -> ('T -> M<'R>) -> M<'R>
val return : 'T -> M<'T>
the delay has the signature of
val delay : (unit -> M<'R>) -> M<'R>
'T being type-bound to unit. Note that your bind function has its arguments reversed from the customary order bind p rest. This is technically same but does complicate reading code.
Since you are defining the monadic type as type Maybe<'a> = option<'a>, there is no delaying a computation, as the type does not wrap any computation at all, only a value. So you definition of delay as let delay f = f() is theoretically correct. But it is not adequate for a while loop: the "body" of the loop will be computed before its "test condition," really before the bind is bound. To avoid this, you redefine your monad with an extra layer of delay: instead of wrapping a value, you wrap a computation that takes a unit and computes the value.
type Maybe<'a> = unit -> option<'a>
let return x = fun () -> Some(x)
let fail = fun() -> None
let bind p rest =
match p() with
| None -> fail
| Some r -> rest r
Note that the wrapped computation is not run until inside the bind function, i. e. not run until after the arguments to bind are bound themselves.
With the above expression, delay is correctly simplified to
let delay f = fun () -> f()

Applying a function to a custom type in F#

On my journey to learning F#, I've run into a problem I cant solve. I have defined a custom type:
type BinTree =
| Node of int * BinTree * BinTree
| Empty
I have made a function which takes a tree, traverses it, and adds the elements it visits to a list, and returns it:
let rec inOrder tree =
seq{
match tree with
| Node (data, left, right) ->
yield! inOrder left
yield data;
yield! inOrder right
| Empty -> ()
}
|> Seq.to_list;
Now I want to create a function, similar to this, which takes a tree and a function, traverses it and applies a function to each node, then returns the tree:
mapInOrder : ('a -> 'b) -> 'a BinTree -> 'b BinTree
This seems easy, and it probably is! But I'm not sure how to return the tree. I've tried this:
let rec mapInOrder f tree =
match tree with
| Node(data, left, right) ->
mapInOrder f left
Node(f(data), left, right)
mapInOrder f right
| Empty -> ()
but this returns a unit. I havent worked with custom types before, so I'm probably missing something there!
Try this:
let rec mapInOrder f = function
| Node(a,l,r) ->
let newL = mapInOrder f l
let b = f a
let newR = mapInOrder f r
Node(b,newL,newR)
| Empty -> Empty
If the function is side-effect free, then traversal order is unimportant and you can instead write:
let rec map f = function
| Node(a,l,r) -> Node(f a, map f l, map f r)
| Empty -> Empty
A match is an expression. It returns the value of the matching case. That implies that all match cases must have the same type. The match expression itself then has that type.
In your first attempt, your Empty clause returned (), and thus had unit type--not the tree type you were looking for.
Since mapInOrder just returns the match result, it too took on unit return type.
The Node clause was fine because its return value is the result of calling mapInOrder, so it also took on unit type and the requirement that all match clauses have the same type was satisfied.
A key change in kvb's suggestion was making the Empty clause return a tree instead of unit. Once you do that, you get compiler errors and warnings pointing to the other problems.
You can often work through issues like this by explicitly coding the type you'd like, and then seeing where the compile errors and warnings show up.

Working with Nullable<'T> in F#

I'm wondering what others have come up with for dealing with Nullable<'T> in F#. I want to use Nullable<'T> on data types so that serialization works properly (i.e., doesn't write out F# option type to XML). But, I don't want my code stuck dealing with the ugliness of dealing with Nullable<'T> directly. Any suggestions?
Is it better to use active patterns to match directly on Nullable, or just a converter to option and use Some/None matching?
Additionally, I'd love to hear ideas on dealing with nullable references in a nice manner too. If I use, say "string option", then I end up with the F# option type wrapping things. If I don't then I can't distinguish between truly optional strings and strings that shouldn't be null.
Any chance .NET 4 will take on an Option<'T> to help out? (If it's part of the BCL, then we might see better support for it...)
As active patterns as options plays nicely with pattern matching, but is seems by using active patterns (i.e. typeof and ??) your code will eat more ticks.
The base question is how you will deal with your nullable references?
In case your code is long chained computations it's nice to use monadic syntax:
type Maybe<'a> = (unit -> 'a option)
let succeed x : Maybe<'a> = fun () -> Some(x)
let fail : Maybe<'a> = fun () -> None
let run (a: Maybe<'a>) = a()
let bind p rest = match run p with None -> fail | Some r -> (rest r)
let delay f = fun () -> run (f ())
type MaybeBuilder() =
member this.Return(x) = succeed x
member this.Let(p,rest) = rest p
member this.Bind(p,rest) = bind p rest
member this.Delay(f) = delay f
let maybe = new MaybeBuilder()
let add (a:'a) (b:'a) =
maybe {
match TryGetNumericAssociation<'a>() with
| Some v -> return (v.Add(a,b))
| _ -> return! fail
}
let add3 (a:'a) (b:'a) (c:'a) =
maybe {
let! ab = add a b
let! abc = add ab c
return abc
}
> let r1 = add 1 2;;
val r1 : (unit -> int option)
> r1();;
val it : int option = Some 3
> let r2 = add "1" "2";;
val r2 : (unit -> string option)
> r2();;
val it : string option = None
> let r3 = add3 "one" "two" "three";;
val r3 : (unit -> string option)
> r3();;
val it : string option = None

Resources