Ho questo due tipi
open FSharpx
open FSharpx.Reader
type First =
{ Name: string
Items: string list }
type Second =
{ Name: string
Numbers: int list }
Usando un monade Reader dalla FSharpx biblioteca posso farlo
let map f =
fun n xs ->
{ Name = n; Items = xs } // : Second
<!> Reader.ask (fun (o:First) -> o.Name)
<*> (List.map f <!> Reader.asks (fun o -> o.Items))
e lo eseguo senza problemi
> let first = {Name="stuff";Items=["1";"2";"3"]}
> map int first;;
val it : Second = {Name = "stuff";
Numbers = [1; 2; 3];}
il problema è che la funzione int
non è sicura, quindi devo protect
in un tipo Choice
.
> let safeInt = Choice.protect int
val safeInt : (int -> Choice<int,exn>)
Ora, come faccio a utilizzare questa funzione nella mia funzione map
da First
a Second
?
il mio tentativo sta utilizzando la corrispondenza dei pattern creando una funzione wrapper con la conoscenza del tipo Choice
let second n = function
| Choice1Of2 xs -> Choice1Of2 {Name=n;Numbers=xs}
| Choice2Of2 err -> Choice2Of2 err
let map' f =
mapping
<!> Reader.ask (fun (o:First) -> o.Name)
<*> (Choice.mapM f <!> Reader.ask (fun o -> o.Items))
ma questo non va bene perché potrebbe sembrare al di fuori del modulo che Second
potrebbe non avere una proprietà Number
C'è un modo migliore per applicare il risultato di un tipo di scelta al mio esempio?