Rash thoughts about .NET, C#, F# and Dynamics NAV.


"Every solution will only lead to new problems."

Monday, 15. August 2011


Some special monads in F# – Part 1 of n – InfinityMonad

Filed under: F#,Informatik — Steffen Forkmann at 15:04 Uhr

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.

https://frpiluleenligne.com
Tags: ,

5 Comments »

  1. […] 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

  2. 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

  3. 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:

    let zeroIfInfinite = function
    | Infinite -> 0.
    | Value x -> x
    
    // 5. Use the safe division in a computation expression
    let totalResistance r1 r2 r3 =
        safe {
            // no DivideByZero exception occurs here
            let! x = divide 1.0 r1
            let! y = divide 1.0 r2
            let! z = divide 1.0 r3
            return! divide 1.0 (x + y + z) 
        } |> zeroIfInfinite
    

    Regards,
    Steffen

    Comment by Steffen Forkmann — Tuesday, 16. August 2011 um 15:35 Uhr

  4. 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

  5. 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

RSS feed for comments on this post. | TrackBack URI

Leave a comment

XHTML ( You can use these tags): <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> .