Note that there are some explanatory texts on larger screens.

plurals
  1. POImplementing the Haskell-MaybeMonad in F# - how can we get this lazy?
    primarykey
    data
    text
    <p>we are trying to build the Haskell-MaybeMonad sample from <a href="http://www.haskell.org/all_about_monads/html/maybemonad.html" rel="noreferrer">http://www.haskell.org/all_about_monads/html/maybemonad.html</a> in F#.</p> <p>The idea is to search for a mailaddress in two dictionaries. If one of the both lookups returns a result we look into the third one. </p> <pre><code>let bindM x k = match x with | Some value -&gt; k value | None -&gt; None let returnM x = Some x type MaybeBuilder() = member this.Bind(x, k) = bindM x k member this.Return(x) = returnM x member this.ReturnFrom(x) = x member this.Delay(f) = f() let maybe = MaybeBuilder() //Sample dictionaries let fullNamesDb = [("Bill Gates", "billg@microsoft.com") ("Bill Clinton", "bill@hope.ar.us") ("Michael Jackson", "mj@wonderland.org") ("No Pref Guy", "guy@nopref.org")] |&gt; Map.ofList let nickNamesDb = [("billy", "billg@microsoft.com") ("slick willy", "bill@hope.ar.us") ("jacko", "mj@wonderland.org") ] |&gt; Map.ofList let prefsDb = [("billg@microsoft.com", "HTML") ("bill@hope.ar.us", "Plain") ("mj@wonderland.org", "HTML")] |&gt; Map.ofList let mplus m1 m2 = if m1 &lt;&gt; None then m1 else m2 let (+) = mplus let lookUp name = maybe { let! combined = fullNamesDb.TryFind name + nickNamesDb.TryFind name return! prefsDb.TryFind combined } let billGatesPref = lookUp "Bill Gates" |&gt; printfn "%A" // Some "HTML" let billyPref = lookUp "billy" |&gt; printfn "%A" // Some "HTML" let billClintonPref = lookUp "Bill Clinton" |&gt; printfn "%A" // Some "Plain" let steffenPref = lookUp "Steffen" |&gt; printfn "%A" // None let noPref = lookUp "No Pref Guy" |&gt; printfn "%A" // None System.Console.ReadKey() |&gt; ignore </code></pre> <p>The problem is that we perform the second lookup even if the first one returns a result. The nice thing about Haskell is here, that it evaluates lazy. Now we looking for something similar in F#. We tried the following but it looks ugly and seems to break the idea of encapsulating the maybe logic in the builder:</p> <pre><code>let mplus m1 m2 = if m1 &lt;&gt; None then m1 else m2() let (+) = mplus let lookUp name = maybe { let! combined = fullNamesDb.TryFind name + fun _ -&gt; nickNamesDb.TryFind name return! prefsDb.TryFind combined } </code></pre> <p>Is there a better solution?</p> <p>Regards, forki</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload