Skip to content

Instantly share code, notes, and snippets.

@nicerobot
Last active December 13, 2015 20:18
Show Gist options
  • Save nicerobot/4968883 to your computer and use it in GitHub Desktop.
Save nicerobot/4968883 to your computer and use it in GitHub Desktop.
Hmm, personally, what's needed is for compilers to provide nice graphs of the structure of the code.

Let's say i want to apply functions a, b, c, and d to each element of a list, xs, such that the result of a is passed to b who's result is passed to c who's result is passed to d. It's:

xs.map(a).map(b).map(c).map(d)

or

xs.map(d(c(b(a(_)))))

To me, that's clear (assuming the naming is clearly defined), but it probably doesn't read well since, at least in english, we read left to right, not inside-out (nor right to left).

It might be nicer to define a function something like:

(x) => a(x) -> b -> c -> d

So, in Scala:

val fs = List(a _, b _, c _, d _)

then just comose them:

val fc = d _ compose c _ compose b _ compose a _

Now you have a function that'll apply d(c(b(a(_)))) and is usable in a map:

xs.map(fc)
def a(x:Int) = x + 1
def b(x:Int) = x / 2
def c(x:Int) = x * 3
def d(x:Int) = x % 4
// The composition:
def fc(x:Int) = d(c(b(a(x))))
// I very much like this, structureally. It explains exactly what's happening.
// But it can be better.
// Maybe:
val fc(x:Int) = (d _ compose c _ compose b _ compose a _)(x)
// But it's a little too verbose and still backwards.
// Can i just define it like:
val fs = List(a _,b _,c _,d _)
// And call fs?
// Yes:
// Just fold the reverse of the list of functions into a composition:
val fc = fs.reverse.head.foldLeft(fs.reverse.tail)(_ compose _)
// More generally:
// Define helpers:
def fcr[A](fs:List[A=>A]) = fs.tail.foldLeft(fs.head)(_ compose _)
def fcg[A](fs:List[A=>A]) = fcr(fs.reverse)
// Then build compositons from lists of functions using :
val fc(x:Int) = fcg(fs)
// TODO I think it can get even better with implicits, to automaticlaly turn a list of functions into a composition.
def fcr[A](fs:List[A=>A]) = fs.tail.foldLeft(fs.head)(_ compose _)
def fcg[A](fs:List[A=>A]) = fcr(fs.reverse)
; From https://gist.github.com/w01fe/3802595
(def stats-graph
{:n (fnk [xs] (count xs))
:m (fnk [xs n] (/ (sum identity xs) n))
:m2 (fnk [xs n] (/ (sum #(* % %) xs) n))
:v (fnk [m m2] (- m2 (* m m)))})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment