3 people like it.

Reinventing the Reader Monad

Alternative solution to the problem in Scott Wlaschin's "Reinventing the Reader Monad" article (but without monads).

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
/// Applies the specified function to all items in the list.
/// If any of the function calls results in a Failure, the
/// map function returns failure immediately.
let mapOrFail f items = 
    let rec loop acc items =
        match items with
        | x::xs -> 
            match f x with
            | Success r -> loop (r::acc) xs
            | fail -> fail
        | [] -> Success(List.rev acc)
    loop [] items


let getPurchaseInfo (custId:CustId)  : Result<ProductInfo list> =

    // Open api connection (I'm not calling 'Close' at the end
    // because this is should be done done automatically, as the
    // client implements IDisposable)
    use api = new ApiClient()
    api.Open()

    // Get product ids purchased by customer id
    let productIdsResult = api.Get<ProductId list> custId
    match productIdsResult with
    | Success productIds -> 
        productIds |> mapOrFail (api.Get<ProductInfo> productId)
    | Failure err -> 
        Failure err 
val mapOrFail : f:('a -> 'b) -> items:'a list -> 'c

Full name: Script.mapOrFail


 Applies the specified function to all items in the list.
 If any of the function calls results in a Failure, the
 map function returns failure immediately.
val f : ('a -> 'b)
val items : 'a list
val loop : ('d -> 'a list -> 'e)
val acc : 'd
val x : 'a
val xs : 'a list
Multiple items
module List

from Microsoft.FSharp.Collections

--------------------
type List<'T> =
  | ( [] )
  | ( :: ) of Head: 'T * Tail: 'T list
  interface IEnumerable
  interface IEnumerable<'T>
  member Head : 'T
  member IsEmpty : bool
  member Item : index:int -> 'T with get
  member Length : int
  member Tail : 'T list
  static member Cons : head:'T * tail:'T list -> 'T list
  static member Empty : 'T list

Full name: Microsoft.FSharp.Collections.List<_>
val rev : list:'T list -> 'T list

Full name: Microsoft.FSharp.Collections.List.rev
val getPurchaseInfo : custId:'a -> 'b

Full name: Script.getPurchaseInfo
val custId : 'a
type 'T list = List<'T>

Full name: Microsoft.FSharp.Collections.list<_>
val api : System.IDisposable
val productIdsResult : obj
Multiple items
val Failure : message:string -> exn

Full name: Microsoft.FSharp.Core.Operators.Failure

--------------------
active recognizer Failure: exn -> string option

Full name: Microsoft.FSharp.Core.Operators.( |Failure|_| )
Next Version Raw view Test code New version

More information

Link:http://fssnip.net/s4
Posted:9 years ago
Author:Tomas Petricek
Tags: monads