3 ms·
Another great exposition on the applicative-order Y combinator can be found at the end of Chapter 9 of The Little Schemer. It is interesting to contrast with h
by kannmig 8y ago
Another great exposition on the applicative-order Y combinator can be found at the end of Chapter 9 of The Little Schemer.
It is interesting to contrast with how in Haskell, one can simply define Y as
Y f = f (Y f)
owing to the fact that it is lazily evaluated.
- snrji 8y agoI'm not proficient in Haskell, but how would the compiler be able to statically type that expression?
- yorwba 8y agoPrelude> y f = f (y f) Prelude> :type y y :: (t -> t) -> t Because f is applied to an argument, it must be a function of generic type t -> u. Because y is applied to f, it must be a function of type (t -> u) -> v. Then the type of y f is v. Because f is applied to y f, t = v. Then the type of f (y f) is u. Because y f is defined as f (y f), the two expressions need to have the same type, t = u. Therefore f is of type t -> t and y is of type (t -> t) -> t.
- user2994cb 8y agoIt's true that the original non-recursive definition of Y doesn't typecheck in Haskell: Prelude> \f->(\x->f(x x))(\x->f(x x)) <interactive>:5:14: Occurs check: cannot construct the infinite type: r0 ~ r0 -> t ...
- evincarofautumn 8y agoOf course, the definition we actually use is this: -- (1) fix f = let x = f x in x Because it has better memory usage; the definition you provided is translated to the following STG: -- (2) fix f = let x = fix f in f x So whereas #1 is a thunk that refers to itself, #2 is a recursive function, and importantly not tail-recursive.