combine reader monad with choice

by fra9001   Last Updated December 03, 2017 19:05 PM

I have this two types

open FSharpx
open FSharpx.Reader

type First =
    { Name: string
      Items: string list }

type Second =
    { Name: string
      Numbers: int list }

Using a Reader monad from the FSharpx library I can do this

let map f =
        fun n xs ->
            { Name = n; Items = xs } // : Second
    <!> Reader.ask (fun (o:First) -> o.Name)
    <*> ( f <!> Reader.asks (fun o -> o.Items))

and I execute this without problem

> let first = {Name="stuff";Items=["1";"2";"3"]}
> map int first;;
val it : Second = {Name = "stuff";
                   Numbers = [1; 2; 3];}

the problem is that the function int is not safe, so I have to protect it into a Choice type.

> let safeInt = Choice.protect int
val safeInt : (int -> Choice<int,exn>)

Now, how do I use this function in my map function from First to Second?

my attempt is using pattern matching by creating a wrapper function with the knowledge of the Choice type

let second n = function
    | Choice1Of2 xs -> Choice1Of2 {Name=n;Numbers=xs}
    | Choice2Of2 err -> Choice2Of2 err

let map' f =
    <!> Reader.ask (fun (o:First) -> o.Name)
    <*> (Choice.mapM f <!> Reader.ask (fun o -> o.Items))

but this is not good because it might seem from outside the module that Second might not have an Number property

Is there a better way to apply the result of a choice type to my example?

Related Questions

Pattern matching in Clojure vs Scala

Updated December 03, 2017 19:05 PM

Pattern matching events with arbitrary structure

Updated December 03, 2017 19:05 PM

Programming language with pattern matching in trees

Updated December 03, 2017 19:05 PM