6

I now understand the type signature of s (s k):

s (s k)  :: ((t1 -> t2) -> t1) -> (t1 -> t2) -> t1

And I can create examples that work without error in the Haskell WinGHCi tool:

Example:

s (s k) (\g -> 2) (\x -> 3)

returns 2.

Example:

s (s k) (\g -> g 3) successor

returns 4.

where successor is defined as so:

successor = (\x -> x + 1)

Nonetheless, I still don't have an intuitive feel for what s (s k) does.

The combinator s (s k) takes any two functions f and g. What does s (s k) do with f and g? Would you give me the big picture on what s (s k) does please?

Gilles 'SO- stop being evil'
  • 104,111
  • 38
  • 209
  • 254
Roger Costello
  • 3,007
  • 1
  • 22
  • 43
  • 1
    The defination for `S (S K)` is missing. Is this the same `s` and `k` in http://stackoverflow.com/questions/9592191/the-type-signature-of-a-combinator-does-not-match-the-type-signature-of-its-equi ? – J-16 SDiZ Mar 12 '12 at 10:07
  • Btw, what is intuitive? Do you found http://en.wikipedia.org/wiki/Ouroboros intuitive? Can you imagine a snake eats itself and vanish? Or a robot that builds itself from itself? You need better sense on something acting on itself. – J-16 SDiZ Mar 12 '12 at 10:12

1 Answers1

11

Alright, let's look at what S (S K) means. I'm going to use these definitions:

S = \x y z -> x z (y z)
K = \x y   -> x

S (S K) = (\x y z -> x z (y z)) ((\x y z -> x z (y z)) (\a b -> a)) -- rename bound variables in K
        = (\x y z -> x z (y z)) (\y z -> (\a b -> a) z (y z)) -- apply S to K
        = (\x y z -> x z (y z)) (\y z -> (\b -> z) (y z)) -- apply K to z
        = (\x y z -> x z (y z)) (\y z -> z) -- apply (\_ -> z) to (y z)
        = (\x y z -> x z (y z)) (\a b -> b) -- rename bound variables
        = (\y z -> (\a b -> b) z (y z)) -- apply S to (\a b -> b)
        = (\y z -> (\b -> b) (y z)) -- apply (\a b -> b) to z
        = (\y z -> y z) -- apply id to (y z)

As you can see, it's just ($) with more specific type.

Vitus
  • 11,822
  • 7
  • 37
  • 64
  • 2
    Another way to see this: the type is `((t1 -> t2) -> t1) -> (t1 -> t2) -> t1`. Adding parentheses, we get `((t1 -> t2) -> t1) -> ((t1 -> t2) -> t1)`. Letting the type `α` stand for `(t1 -> t2) -> t1`, this is just `α -> α`, and so, by parametricity, `s (s k)` is the identity function with a more specific type. (And of course, `($) :: (a -> b) -> a -> b` is *also* just the identity function with a more specific type.) – Antal Spector-Zabusky Mar 12 '12 at 18:49
  • Indeed, if we η-reduce `\y -> \z -> y z`, we get `\y -> y`. – Vitus Mar 12 '12 at 20:06
  • 1
    In combinators, S K y z = K z (y z) = z. Then S (S K) y z = S K z (y z) = K (y z) (z (y z)) = y z. – rickythesk8r Mar 13 '12 at 21:13
  • 3
    @AntalS-Z, it's a bit cheeky to appeal to parametricity on a type you generalised yourself :P it's true that the type here pretty much demands that the function is a type-restricted identity, but e.g. `(a -> a) -> (a -> a)` is another type that is `α -> α` for some `α`, yet has plenty of non-identity values. – Ben Millwood Mar 14 '12 at 00:22
  • @benmachine: This is what I get for playing fast and loose with free theorems. Duly noted :-) – Antal Spector-Zabusky Mar 14 '12 at 01:45