Quantcast
Channel: Active questions tagged ocaml - Stack Overflow
Viewing all articles
Browse latest Browse all 518

Inverting chained maps?

$
0
0

A very common pattern in functional programming is to chain a series of calls to map on lists. A contrived, simple example:

[1; 2; 3] |> List.map (fun x -> x + 1) |> List.map (fun x -> x * 2)

Where the result is:

[4; 6; 8]

Now it's easy enough to flip this on its head and avoid the creation of lists at each stage, if the types never change: simply have map take a list of functions to apply in order:

let list_map_chained : 'a. ('a -> 'a) list -> 'a list -> 'a list =  let rec apply x chain =    begin match chain with    | []          -> x    | f :: chain' -> apply (x |> f) chain'    end  in  fun chain xs ->    List.map (fun x -> apply x chain) xs

Which we can use like this:

[1; 2; 3] |> list_map_chained [ (fun x -> x + 1) ; (fun x -> 2 * x) ]

But if we want to do the same thing to a sequence like the following:

[1; 2; 3] |> List.map (fun x -> x + 1)           |> List.map (fun x -> x * 2)          |> List.map (fun x -> float_of_int x /. 3.)

Now the types do change, but because of the heterogenous nature of the types, the functions cannot be stored in anything like a list that expects (and requires) homogenous types. Obviously this is very straightforward in a less strictly typed programming language like Ruby:

class Array  def inverted_map(*lambdas)    self.map { |x| lambdas.inject(x) { |sum, l| l.call(sum) } }  endendirb(main):032:0> [1,2,3].inverted_map(lambda { |x| x + 1 }, lambda { |x| x * 2 }, lambda { |x| x.to_f / 3})=> [1.3333333333333333, 2.0, 2.6666666666666665]

I know a fair amount about Ocaml, but I am open to not knowing it all. Is there a way to accomplish this within Ocaml's type system that is not more trouble than it's worth?


Viewing all articles
Browse latest Browse all 518

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>