Search code examples
smlfold

Composition using foldr SML


Is there any way to do something like a(b(c(5))) from a variable that contains the functions?

The code would be something like that:

val a = fn x => x + 10
val b = fn x => x * x
val c = fn x => (x - 2) * 3
val fs = [a, b, c]

Solution

  • You can apply op to the composition operator o so that it can be used as a function, and then use that function with foldr to fold the list of functions down to a single function. Use the identity function as an initial value.

    Thus, foldr (op o) identity [a, b, c] is equivalent to a o (b o (c o identity)), where identity is the identity function:

    fun identity x = x;
    

    Using the posted definitions for a, b, c, and fs it's not too bad to write OP example as a one-liner:

    - (foldr (op o) (fn x => x) fs) 5;
    val it = 91 : int
    - a(b(c 5));
    val it = 91 : int
    

    It's a bit easier if identity has been defined, but even nicer to define a higher-order function to abstract this away:

    fun composeList fs = foldr (op o) (fn x => x) fs;
    
    - composeList fs 5;
    val it = 91 : int