First, here are a couple of map functions adapted from the example on page 148 of RWFP. Please excuse my quick-and-dirty naming conventions. For clarity in this example only, I named the map functions “map12” for “map one function onto a two-tuple” and “map22” for “map two functions onto a two-tuple.”
let map12 f (a,b) = ((f a),(f b))
let map22 f g (a,b) = ((f a),(g b))
Here are my pipeline operators. The (||>) works like (|> map12), while the second two act like (map22 |>). (||>>) takes tupled functions, while (||>>> takes curried functions.
let (||>) (a,b) f = ((f a),(f b))
let (||>>) (a,b) (f,g) = ((f a),(g b))
let (||>>>) (a,b) f g = ((f a),(g b))
And here is a small test. Each example partitions a list of integers into lists of even and odd integers, creates a list of the halves of the even integers and the doubles of the odd integers, then sums the two lists and returns the sums as a tuple. (This is probably a useless task, but it demonstrates the operation without as much fluff as the real-world example I was working on.)
let isEven n = (n%2)=0
let doubleIt n = n*2
let halveIt n = n/2
let nums = [0..19]
let a =
List.partition isEven nums
|> map22 (List.map halveIt) (List.map doubleIt)
|> map12 List.sum
let b =
List.partition isEven nums
||>> (List.map halveIt, List.map doubleIt)
||> List.sum
let c =
List.partition isEven nums
||>>> (List.map halveIt) <| (List.map doubleIt)
||> List.sum
All are fairly readable; in general, I prefer the RWFP approach because I feel it better extends the language than does a custom operator. But it would probably be possible to find design situations where any of the three was appropriate.
No comments:
Post a Comment