Search code examples
f#functional-programmingsamplecombinatorsk-combinator

(Kestrel) K-combinator: why is it useful?


I have been taking up F# recently (my background is C#) and am reading the site http://fsharpforfunandprofit.com, which I am finding very helpful.

I've got to http://fsharpforfunandprofit.com/posts/defining-functions/ which is the section on combinators. I understand them all (although the Y combinator or Sage bird screws with my mind!) with the exception of the Kestrel. Scott Wlaschin gives the definition (in F#) as:

let K x y = x

I can't understand for the life of me any situation in which this would be useful. At first I thought it might be used as chain operator, so that you can pass a value to a function and then get back the original value. I've written such an operator myself before, but as you can see it's not the same:

let (>|) x f = f x; x

If we partially apply the K combinator (with the value 5) then we get back a function that ignores its argument and instead returns 5. Again, not useful.

(K 5) = fun y -> 5

Can anyone give me an easy example of where this might be used please?


Solution

  • Here is a very easy example:

    Let's suppose I have a structure, like a list where I can map functions.

    let K x y = x
    
    let lst = [3;5;13;2]
    

    I can map math functions like this:

    let plus5  = lst |> List.map ((+)5) // instead of writing List.map (fun x -> 5 + x)
    // val plus5 : int list = [8; 10; 18; 7]
    
    let times3 = lst |> List.map ((*)3) // instead of writing List.map (fun x -> 3 * x)
    // val times3 : int list = [9; 15; 39; 6]
    

    What if I want to map a constant function?

    let tens = lst |> List.map (K 10) // instead of writing List.map (fun x -> 10)
    // val tens : int list = [10; 10; 10; 10]
    

    Given that in FP you typically pass functions as arguments, the K combinator allows you to specify a constant function with a few keystrokes.