F# Monad multiple parameters - f#

I am trying to wrap my head around monads and how to use them in real world examples. The first "task" i set myself is to write an "Exception Monad" which of course (at this point) is nothing more than the "Either monad" twisted to suit my purpose.
My code looks like this:
type MException<'a> =
| Success of 'a
| Failure of string
with
static member returnM a =
Success a
static member bind f =
fun e ->
match e with
| Success a -> f a
| Failure m -> Failure m
static member map f =
fun e ->
match e with
| Success a -> Success (f a)
| Failure m -> Failure m
// Create a little test case to test my code
let divide (n, m) =
match m with
| 0 -> Failure "Cannot divide by zero"
| _ -> Success ((float n) / (float m))
let round (f:float) =
Success ( System.Math.Round(f, 3) )
let toString (f:float) =
sprintf "%f" f
let divideRoundAndPrintNumber =
divide
>> MException<_>.bind round
>> MException<_>.map toString
// write the result
let result = divideRoundAndPrintNumber (11, 3)
match result with
| Success r -> printf "%s\n" r
| Failure m -> printf "%s\n" m
My question is the following: the divide function now takes a tuple. What can or should I do to make the bind and map functions behave correctly for functions with multiple parameters?
EDIT 30-12-2015:
Both the answers and comments of #Mark Seemann helped find the answer to the problem. #Mikhail provided the implementation of the solution. Currying is the right way of solving the problem. Computation Expressions are not a solution but a syntax abstraction which does work but gets complicated once you add async and other patterns to the problem. "Simple" composition seems like the easiest and "trueest" solution.

Change divideRoundAndPrintNumber to be a function instead of a value
let divide n m =
match m with
| 0 -> Failure "Cannot divide by zero"
| _ -> Success ((float n) / (float m))
let divideRoundAndPrintNumber n =
divide n
>> MException<_>.bind round
>> MException<_>.map toString

Unfortunately I do not know enough about F# to understand your code completely. For example I do not understand the >> operator and the MException<_> expression. But I can give you an alternative solution for your problem. It utilzies a F# feature called "Computation Expressions". It enables you to do "Monadic" magic in a nice F#-like way:
type MException<'a> =
| Success of 'a
| Failure of string
type ExceptionBuilder() =
member this.Bind (m, f) =
match m with
| Success a -> f a
| Failure m -> Failure m
member this.Return (x) =
Success (x)
let ex = new ExceptionBuilder()
let divide n m =
if m = 0 then Failure "Cannot divide by zero"
else Success ((float n)/(float m))
let round (f : float) =
Success (System.Math.Round(f, 3))
let divideRoundAndPrintNumber a b =
ex {
let! c = divide a b
let! d = round c
printf "result of divideRoundAndPrintNumber: %f\n" d
return d
}
let result = divideRoundAndPrintNumber 11 0
match result with
| Success r -> printf "%f\n" r
| Failure m -> printf "%s\n" m
Apologies when my answer does not match your question completely but I hope it helps.
Here you can find an excellent blog post series about this topic:
http://fsharpforfunandprofit.com/posts/computation-expressions-intro/
I also found this article very enlightening:
http://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html

Monads have a fairly strict required structure, they must have:
Return: 'a -> m<'a>
and
Bind: m<'a> -> ('a -> m<'b>) -> m<'b>
Your divide function has the signature int*int -> MException<float>, i.e. it does indeed have the required 'a -> m<'b> form to be used with bind. When used with bind, it would act on something of type MException<int*int> and produce an MException<float>.
If divide is instead of type int -> int -> MException<float> (i.e. 'a -> 'b -> m<'c>'), we can't use it with bind directly. What we can do is unwrap the tuple and then supply the arguments one by one to create a lambda that does have the right form.
Let's add an extra Return so that we can see more clearly some different approaches for handling functions within these constraints:
let divideTupled (n, m) =
match m with
| 0 -> Failure "Cannot divide by zero"
| _ -> Success ((float n) / (float m))
let divideRoundAndPrintNumber n m =
MException<_>.Return (n,m)
|> MException<_>.Bind divideTupled
|> MException<_>.Bind round
|> MException<_>.Map toString
or
let divideCurried n m =
match m with
| 0 -> Failure "Cannot divide by zero"
| _ -> Success ((float n) / (float m))
let divideRoundAndPrintNumber n m =
MException<_>.Return (n,m)
|> MException<_>.Bind (fun (n,m) -> divideCurried n m)
|> MException<_>.Bind round
|> MException<_>.Map toString
Computation expressions, as mentioned by Olaf, provide some nice syntactic sugar for working with monads in F#.

Why not define divide like you normally would?
let divide n m =
match m with
| 0 -> Failure "Cannot divide by zero"
| _ -> Success ((float n) / (float m))
You could then define divideRoundAndPrintNumber like this, likewise in curried form:
let divideRoundAndPrintNumber n m =
divide n m
|> MException<_>.bind round
|> MException<_>.map toString
FSI ad-hoc tests:
> let result = divideRoundAndPrintNumber 11 3;;
val result : MException<string> = Success "3.667000"
> let result = divideRoundAndPrintNumber 11 0;;
val result : MException<string> = Failure "Cannot divide by zero"

Related

Railway Oriented Programming and partial application

I like using ROP when I have to deal with IO/Parsing strings/...
However let's say that I have a function taking 2 parameters. How can you do clean/readable partial application when your 2 parameters are already a Result<'a,'b> (not necessary same 'a, 'b)?
For now, what I do is that I use tuple to pass parameters and use the function below to get a Result of a tuple so I can then bind my function with this "tuple-parameter".
/// Transform a tuple of Result in a Result of tuple
let tupleAllResult x =
match (fst x, snd x) with
| Result.Ok a, Result.Ok b -> (a,b) |> Result.Ok
| Result.Ok a, Result.Error b -> b |> Result.Error
| Result.Error a, _ -> a |> Result.Error
let f (a: 'T, b: 'U) = // something
(A, B) |> tupleAllResult
|> (Result.bind f)
Any good idea?
Here what I wrote, which works but might not be the most elegant
let resultFunc (f: Result<('a -> Result<'b, 'c>), 'd>) a =
match f with
| Result.Ok g -> (g a) |> Result.Ok |> Result.flatten
| Result.Error e -> e |> Result.Error |> Result.flatten
I am not seeing partial application in your example, a concept related to currying and argument passing -- that's why I am assuming that you are after the monadic apply, in that you want to transform a function wrapped as a Result value into a function that takes a Result and returns another Result.
let (.>>.) aR bR = // This is "tupleAllResult" under a different name
match aR, bR with
| Ok a, Ok b -> Ok(a, b)
| Error e, _ | _, Error e -> Error e
// val ( .>>. ) : aR:Result<'a,'b> -> bR:Result<'c,'b> -> Result<('a * 'c),'b>
let (<*>) fR xR = // This is another name for "apply"
(fR .>>. xR) |> Result.map (fun (f, x) -> f x)
// val ( <*> ) : fR:Result<('a -> 'b),'c> -> xR:Result<'a,'c> -> Result<'b,'c>
The difference to what you have in your question is map instead of bind in the last line.
Now you can start to lift functions into the Result world:
let lift2 f xR yR =
Ok f <*> xR <*> yR
// val lift2 :
// f:('a -> 'b -> 'c) -> xR:Result<'a,'d> -> yR:Result<'b,'d> -> Result<'c,'d>
let res : Result<_,unit> = lift2 (+) (Ok 1) (Ok 2)
// val res : Result<int,unit> = Ok 3

using a sequence on partial application

I have a sequence of value that I would like to apply to a function partially :
let f a b c d e= a+b+c+d+e
let items = [1,2,3,4,5]
let result = applyPartially f items
Assert.Equal(15, result)
I am looking after the applyPartially function. I have tried writing recursive functions like this :
let rec applyPartially f items =
| [] -> f
| [x] -> f x
| head :: tail -> applyPartially (f head) tail
The problem I have encountered is that the f type is at the beginning of my iteration 'a->'b->'c->'d->'e, and for every loop it should consume an order.
'a->'b->'c->'d->'e
'b->'c->'d->'e
'c->'d->'e
'd->'e
That means that the lower interface I can think of would be 'd->'e. How could I hide the complexity of my function so that only 'd->'e is shown in the recursive function?
The F# type system does not have a nice way of working with ordinary functions in a way you are suggesting - to do this, you'd need to make sure that the length of the list matches the number of arguments of the function, which is not possible with ordinary lists and functions.
However, you can model this nicely using a discriminated union. You can define a partial function, which has either completed, or needs one more input:
type PartialFunction<'T, 'R> =
| Completed of 'R
| NeedsMore of ('T -> PartialFunction<'T, 'R>)
Your function f can now be written (with a slightly ugly syntax) as a PartialFunction<int, int> that keeps taking 5 inputs and then returns the result:
let f =
NeedsMore(fun a -> NeedsMore(fun b ->
NeedsMore(fun c -> NeedsMore(fun d ->
NeedsMore(fun e -> Completed(a+b+c+d+e))))))
Now you can implement applyPartially by deconstructing the list of arguments and applying them one by one to the partial function until you get the result:
let rec applyPartially f items =
match f, items with
| Completed r, _ -> r
| NeedsMore f, head::tail -> applyPartially (f head) tail
| NeedsMore _, _ -> failwith "Insufficient number of arguments"
The following now returns 15 as expected:
applyPartially f [1;2;3;4;5]
Disclaimer: Please don't use this. This is just plain evil.
let apply f v =
let args = v |> Seq.toArray
f.GetType().GetMethods()
|> Array.tryFind (fun m -> m.Name = "Invoke" && Array.length (m.GetParameters()) = Array.length args)
|> function None -> failwith "Not enough args" | Some(m) -> m.Invoke(f, args)
Just like you would expect:
let f a b c d e= a+b+c+d+e
apply f [1; 2; 3; 4; 5] //15

Is there a way to make this continuation passing with codata example work in F#?

type Interpreter<'a> =
| RegularInterpreter of (int -> 'a)
| StringInterpreter of (string -> 'a)
let add<'a> (x: 'a) (y: 'a) (in_: Interpreter<'a>): 'a =
match in_ with
| RegularInterpreter r ->
x+y |> r
| StringInterpreter r ->
sprintf "(%s + %s)" x y |> r
The error message of it not being able to resolve 'a at compile time is pretty clear to me. I am guessing that the answer to the question of whether it is possible to make the above work is no, short of adding functions directly into the datatype. But then I might as well use an interface, or get rid of generic parameters entirely.
Edit: Mark's reply does in fact do what I asked, but let me extend the question as I did not explain it adequately. What I am trying to do is do with the technique above is imitate what what was done in this post. The motivation for this is to avoid inlined functions as they have poor composability - they can't be passed as lambdas without having their generic arguments specialized.
I was hoping that I might be able to work around it by passing an union type with a generic argument into a closure, but...
type Interpreter<'a> =
| RegularInterpreter of (int -> 'a)
| StringInterpreter of (string -> 'a)
let val_ x in_ =
match in_ with
| RegularInterpreter r -> r x
| StringInterpreter r -> r (string x)
let inline add x y in_ =
match in_ with
| RegularInterpreter r ->
x in_ + y in_ |> r
| StringInterpreter r ->
sprintf "(%A + %A)" (x in_) (y in_) |> r
let inline mult x y in_ =
match in_ with
| RegularInterpreter r ->
x in_ * y in_ |> r
| StringInterpreter r ->
sprintf "(%A * %A)" (x in_) (y in_) |> r
let inline r2 in_ = add (val_ 1) (val_ 3) in_
r2 (RegularInterpreter id)
r2 (StringInterpreter id) // Type error.
This last line gives a type error. Is there a way around this? Though I'd prefer the functions to not be inlined due to the limits they place on composability.
Remove the type annotations:
let inline add x y in_ =
match in_ with
| RegularInterpreter r ->
x + y |> r
| StringInterpreter r ->
sprintf "(%A + %A)" x y |> r
You'll also need to make a few other changes, which I've also incorporated above:
Change the format specifiers used with sprintf to something more generic. When you use %s, you're saying that the argument for that placeholder must be a string, so the compiler would infer x and y to be string values.
Add the inline keyword.
With these changes, the inferred type of add is now:
x: ^a -> y: ^b -> in_:Interpreter<'c> -> 'c
when ( ^a or ^b) : (static member ( + ) : ^a * ^b -> int)
You'll notice that it works for any type where + is defined as turning the input arguments into int. In practice, that's probably going to mean only int itself, unless you define a custom operator.
FSI smoke tests:
> add 3 2 (RegularInterpreter id);;
val it : int = 5
> add 2 3 (StringInterpreter (fun _ -> 42));;
val it : int = 42
The compiler ends up defaulting to int, and the kind of polymorphism you want is difficult to achieve in F#. This article articulates the point.
Perhaps, you could work the dark arts using FSharp.Interop.Dynamic but you lose compile time checking which sort of defeats the point.
I've come to the conclusion that what I am trying to is impossible. I had a hunch that it was already, but the proof is in the following:
let vale (x,_,_) = x
let adde (_,x,_) = x
let multe (_,_,x) = x
let val_ x d =
let f = vale d
f x
let add x y d =
let f = adde d
f (x d) (y d)
let mult x y d =
let f = multe d
f (x d) (y d)
let in_1 =
let val_ (x: int) = x
let add x y = x+y
let mult x y = x*y
val_,add,mult
let in_2 =
let val_ (x: int) = string x
let add x y = sprintf "(%s + %s)" x y
let mult x y = sprintf "(%s * %s)" x y
val_,add,mult
let r2 d = add (val_ 1) (val_ 3) d
//let test x = x in_1, x in_2 // Type error.
let a2 = r2 in_1 // Works
let b2 = r2 in_2 // Works
The reasoning goes that if it cannot be done with plain functions passed as arguments, then it definitely won't be possible with interfaces, records, discriminated unions or any other scheme. The standard functions are more generic than any of the above, and if they cannot do it then this is a fundamental limitation of the language.
It is not the lack of HKTs that make the code ungeneric, but something as simple as this. In fact, going by the Finally Tagless paper linked to in the Reddit post, Haskell has the same problem with needing to duplicate interpreters without the impredicative types extension - though I've looked around and it seem that impredicative types will be removed in the future as the extension is difficult to maintain.
Nevertheless, I do hope this is only a current limitation of F#. If the language was dynamic, the code segment above would in fact run correctly.
Unfortunately, it's not completely clear to me what you're trying to do. However, it seems likely that it's possible by creating an interface with a generic method. For example, here's how you could get the code from your answer to work:
type I = abstract Apply : ((int -> 'a) * ('a -> 'a -> 'a) * ('a -> 'a -> 'a)) -> 'a
//let test x = x in_1, x in_2 // Type error.
let test (i:I) = i.Apply in_1, i.Apply in_2
let r2' = { new I with member __.Apply d = add (val_ 1) (val_ 3) d }
test r2' // no problem
If you want to use a value (e.g. a function input) generically, then in most cases the cleanest way is to create an interface with a generic method whose signature expresses the required polymorphism.

Type mismatch error

Here is my code:
open System
let rec gcd a b =
match b with
| x when x = 0 -> a
| _ -> gcd(b, a % b)
let result = gcd 15 10
[<EntryPoint>]
let main(args : string[]) =
printfn "result = %d" result
0
Why I get the error with this code:
D:\datahub\Dropbox\development\myprojects\project-euler\Problem_5\problem_5.fs(6,16): error FS0001: Type mismatch. Expec
ting a
'a
but given a
int -> 'a
The resulting type would be infinite when unifying ''a' and 'int -> 'a'
The example tries to separate arguments by using a comma. In F# multiple arguments are supplied to a function by separating them with whitespace:
let rec gcd a b =
match b with
| x when x = 0 -> a
| _ -> gcd b (a % b)

Why is this F# sequence function not tail recursive?

Disclosure: this came up in FsCheck, an F# random testing framework I maintain. I have a solution, but I do not like it. Moreover, I do not understand the problem - it was merely circumvented.
A fairly standard implementation of (monadic, if we're going to use big words) sequence is:
let sequence l =
let k m m' = gen { let! x = m
let! xs = m'
return (x::xs) }
List.foldBack k l (gen { return [] })
Where gen can be replaced by a computation builder of choice. Unfortunately, that implementation consumes stack space, and so eventually stack overflows if the list is long enough.The question is: why? I know in principle foldBack is not tail recursive, but the clever bunnies of the F# team have circumvented that in the foldBack implementation. Is there a problem in the computation builder implementation?
If I change the implementation to the below, everything is fine:
let sequence l =
let rec go gs acc size r0 =
match gs with
| [] -> List.rev acc
| (Gen g)::gs' ->
let r1,r2 = split r0
let y = g size r1
go gs' (y::acc) size r2
Gen(fun n r -> go l [] n r)
For completeness, the Gen type and computation builder can be found in the FsCheck source
Building on Tomas's answer, let's define two modules:
module Kurt =
type Gen<'a> = Gen of (int -> 'a)
let unit x = Gen (fun _ -> x)
let bind k (Gen m) =
Gen (fun n ->
let (Gen m') = k (m n)
m' n)
type GenBuilder() =
member x.Return(v) = unit v
member x.Bind(v,f) = bind f v
let gen = GenBuilder()
module Tomas =
type Gen<'a> = Gen of (int -> ('a -> unit) -> unit)
let unit x = Gen (fun _ f -> f x)
let bind k (Gen m) =
Gen (fun n f ->
m n (fun r ->
let (Gen m') = k r
m' n f))
type GenBuilder() =
member x.Return v = unit v
member x.Bind(v,f) = bind f v
let gen = GenBuilder()
To simplify things a bit, let's rewrite your original sequence function as
let rec sequence = function
| [] -> gen { return [] }
| m::ms -> gen {
let! x = m
let! xs = sequence ms
return x::xs }
Now, sequence [for i in 1 .. 100000 -> unit i] will run to completion regardless of whether sequence is defined in terms of Kurt.gen or Tomas.gen. The issue is not that sequence causes a stack overflow when using your definitions, it's that the function returned from the call to sequence causes a stack overflow when it is called.
To see why this is so, let's expand the definition of sequence in terms of the underlying monadic operations:
let rec sequence = function
| [] -> unit []
| m::ms ->
bind (fun x -> bind (fun xs -> unit (x::xs)) (sequence ms)) m
Inlining the Kurt.unit and Kurt.bind values and simplifying like crazy, we get
let rec sequence = function
| [] -> Kurt.Gen(fun _ -> [])
| (Kurt.Gen m)::ms ->
Kurt.Gen(fun n ->
let (Kurt.Gen ms') = sequence ms
(m n)::(ms' n))
Now it's hopefully clear why calling let (Kurt.Gen f) = sequence [for i in 1 .. 1000000 -> unit i] in f 0 overflows the stack: f requires a non-tail-recursive call to sequence and evaluation of the resulting function, so there will be one stack frame for each recursive call.
Inlining Tomas.unit and Tomas.bind into the definition of sequence instead, we get the following simplified version:
let rec sequence = function
| [] -> Tomas.Gen (fun _ f -> f [])
| (Tomas.Gen m)::ms ->
Tomas.Gen(fun n f ->
m n (fun r ->
let (Tomas.Gen ms') = sequence ms
ms' n (fun rs -> f (r::rs))))
Reasoning about this variant is tricky. You can empirically verify that it won't blow the stack for some arbitrarily large inputs (as Tomas shows in his answer), and you can step through the evaluation to convince yourself of this fact. However, the stack consumption depends on the Gen instances in the list that's passed in, and it is possible to blow the stack for inputs that aren't themselves tail recursive:
// ok
let (Tomas.Gen f) = sequence [for i in 1 .. 1000000 -> unit i]
f 0 (fun list -> printfn "%i" list.Length)
// not ok...
let (Tomas.Gen f) = sequence [for i in 1 .. 1000000 -> Gen(fun _ f -> f i; printfn "%i" i)]
f 0 (fun list -> printfn "%i" list.Length)
You're correct - the reason why you're getting a stack overflow is that the bind operation of the monad needs to be tail-recursive (because it is used to aggregate values during folding).
The monad used in FsCheck is essentially a state monad (it keeps the current generator and some number). I simplified it a bit and got something like:
type Gen<'a> = Gen of (int -> 'a)
let unit x = Gen (fun n -> x)
let bind k (Gen m) =
Gen (fun n ->
let (Gen m') = k (m n)
m' n)
Here, the bind function is not tail-recursive because it calls k and then does some more work. You can change the monad to be a continuation monad. It is implemented as a function that takes the state and a continuation - a function that is called with the result as an argument. For this monad, you can make bind tail recursive:
type Gen<'a> = Gen of (int -> ('a -> unit) -> unit)
let unit x = Gen (fun n f -> f x)
let bind k (Gen m) =
Gen (fun n f ->
m n (fun r ->
let (Gen m') = k r
m' n f))
The following example will not stack overflow (and it did with the original implementation):
let sequence l =
let k m m' =
m |> bind (fun x ->
m' |> bind (fun xs ->
unit (x::xs)))
List.foldBack k l (unit [])
let (Gen f) = sequence [ for i in 1 .. 100000 -> unit i ]
f 0 (fun list -> printfn "%d" list.Length)

Resources