At the moment I am collecting some samples for the FSharp.Monad project (you get the bits from nuget.org) and I think I should describe some of these monads here, since they are not that common.
Today I will start with a very small monad which encapsulates infinity as a special value. I found the the idea to this specific monad at http://visualizationtools.net. Let’s start with the basic definition. Like every monad we need a container type and the two functions return and bind. Return will be used to get values into the monad and bind allows us to chain functions inside the monad.
The next thing is to create a computation expression builder which allows us to use the nice syntactic sugar in F#.
Now we can start using the monad. As a small sample we define a safe division function which treats all “division by zero” cases as infinity.
And we can use this division inside computation expressions.
Remark: You can easily define this InfinityMonad in terms of the common MaybeMonad. You can see this in the UnitTests of the FSharp.Monad project.
Next time I will show an UndoMonad which defines an environment which allows to undo and redo state changes.
Tags: F#, monad
[…] Some special monads in F# – Part 1 of n – InfinityMonad and Some special monads in F# – Part 2 of n – UndoMonad and Some special monads in F# – Part 3 of n – DistributionMonad and Some special monads in F# – Part 4 of n – Application: The Monty Hall problem (Steffen Forkmann) […]
Pingback by Dew Drop – August 16, 2011 | Alvin Ashcraft's Morning Dew — Tuesday, 16. August 2011 um 12:00 Uhr
shouldn’t the result of the totalResistance be zero?
maybe like this:
let divide x y =
match y with
| 0.0 -> Infinite
| Infinite -> 0.0
| _ -> Value(x/y)
Comment by Stefan Noack — Tuesday, 16. August 2011 um 12:18 Uhr
Hi Stefan,
you are right the semantics are wrong for parallel resistors. Unfortunately your divide function has a type error. But we coud fix this with:
Regards,
Steffen
Comment by Steffen Forkmann — Tuesday, 16. August 2011 um 15:35 Uhr
hm.. but now two infinite resistors in parallel would make a zero resistor, too. but it looks like Infinite isn’t allowed for r1 through r3 anyways.
Comment by Stefan Noack — Wednesday, 17. August 2011 um 13:22 Uhr
actually saying, float numbers division will never get DivideByZeroException
let dummy = 1.0 / 0.0
printfn “%f” dummy
Result, as expected, infinity.
But example itself is great. I’s possibly the simplest “real-life” monad. Id monad is slightly more abstract.
Comment by oleg — Wednesday, 17. August 2011 um 20:42 Uhr