How to turn Integer-List Generator [m ...] in Lambda Calculus in Haskell - haskell

I have given a task to make the Integer-List Generator [m...] in lambda calculus.
So it should fullfill this definition.
Y F m ≡ : m (Y F (+ m 1))
Therefor a lambda calculus F is needed.
I don't know how to find which lambda calculus F should be.
Does anyone have any suggestions for F?

Equational reasoning gets you where you need to go. We have these two equations:
Y F = F (Y F) -- the basic useful property of Y
Y F m = : m (Y F (+ m 1))
So now we just solve. We replace the Y F in Y F m = ... with the thing it's equal to:
F (Y F) m = : m (Y F (+ m 1))
One solution to this equation is to generalize from Y F to an arbitrary variable g everywhere:
F g m = : m (g (+ m 1))
Done. This is now a fine defining equation for F. If you don't like the syntax sugar, you could instead write it as a lambda:
F = \g m -> : m (g (+ m 1))
Of course, when you practice this yourself on other problems, be kind to yourself: there are lots of different choices of how to rewrite things at each step, and you might have to play with a couple different ways before you stumble on one that gets you where you want to go, rather than following such a straight-line path as I've outlined here where I had already tried and eliminated a bunch of wrong ways. Persevere, and you can learn to do it.

I would like to provide some notes on the relationship of [m..] and y f m = m : (y f (+ m 1)). Starting with the observation
[m..] = m : [m+1..]
and replacing [m..] using g m = [m..], we arrive at
g m = m : (g (m+1))
Taken as a definition of g, observe that this is a recursive definition. Recursive definitions can be split into a generic recursive part y (given by y f = f (y f)) and a non-recursive part f
g = y f
This replaces the recursive g by the non-recursive f which we still have to determine/solve for. Substituting g in the previous equation gives
y f m = m : (y f (m+1))
The take away message is that a recursive function (g) can be refactored into a non-recursive function (f). All you need is a single recursive function (y) which you can reuse for other recursive functions/problems.

Related

Dot in haskell, tricky example

I know that "haskells dot" question was answered couple times before on stackoverflow but I came across a example that shows me I still don't fully get it. Let's say I have functions
f :: Integer -> Integer
f x = x
g x = \y -> y
Now, as far as I know dot works like function composition -> f (g x) = (f . g) x
. So
(f . g) 4 5
shuld returns 5. Because g takes two arguments and returns second one, and f is simply identity. However it doesn't, Im getting Couldn't match type error. I have a feeling that haskell parses this expresion to something like ((f . g) 4) 5. But I need deeper explanation
As mentioned in the question, we have:
(f . g) x = f (g x)
Hence, in particular
(f . g) 4 = f (g 4) (*)
from which we have
(f . g) 4 5
= -- application associates to the left
((f . g) 4) 5
= -- equation (*) above
(f (g 4)) 5 =
= -- application associates to the left
f (g 4) 5
We can now see that the last argument 5 is being left as the second argument of f, and not passed to g.
It is useful to remember that Haskell functions are curried: technically, there's no such a thing as a function which takes two arguments. A function having type a -> b -> c is actually a unary function returning a unary function, even if we like to think of that as a binary function.
The composition operator works on unary functions as well: f . g composes the unary functions f and g. If f is "binary", it is treated as a unary function returning a function. This makes it take an additional argument, as shown above. If g is "binary", its returned function is passed to f.
So, using the above definitions:
f x = x
g x = \y -> y
we get:
(f . g) 4 5
= -- done above
f (g 4) 5
= -- associativity
(f (g 4)) 5
= -- definition of f
(g 4) 5
= -- definition of g
(\y -> y) 5
= -- beta reduction
5
main = print $(f . g) 4 5
f x = x
g x = \y -> y
Compiles nicely and when run prints 5. I'm using GHC 8.0.1.
Maybe you'd rather provide a complete minimal etc. example?

Making a range verb in J

J is a fantastic programming language that I have decided to learn. As a simple exercise, I decided to emulate a range. There is a builtin function i. that creates a range 0..i-1. Using some math, I have that this is the range between a and b:
a + i. (b - a - 1)
Success! I thought. Now, the "simple" task of converting to a verb is set before me. This is my problem now. I have a (the left argument) being called on both sides of the verb +. I thought of using evoke, but I am not sure as how to make it work.
So my question stands: How do I convert an expression of the form a f (a g b) or, more specifically, a f (a g b h c) (and similar forms) to a pure verb? I don't want to use explicit arguments, for what's the fun in that? ;)
EDIT My solution is as thus:
range =: [(+i.)>:#-~
To convert an expression of the form x f (x g y) to a form of x h y you can use a dyadic fork:
x (F G H) y = (x F y) G (x H y)
and the identity verb: x [ y = x, making:
x ([ f g) y = (x [ y) f (x g y) = x f (x g y)
So the verb you are looking for is h =: [ f g

Haskell pattern matching inside parentheses

I would like to define a function that operates on an expression of a certain type, but has access to its internal structure, if it has one. For instance, f in what follows:
g :: a -> a -> a
g x y = y
f :: a -> a
f x'#(g x y) = x'
f _ = 1
(g x y) is of type a, so f should be able to take it as an argument, but the definition for f above can't be parsed by Haskell. I would like to define something like f to take advantage of call-by-name evaluation. Is there any way to do this in Haskell?
First, pattern matching is allowed only on patterns, i.e. expressions built from application, constructors, and variables (used at most once).
Second, even if it were extended, your example is problematic because your g is not injective:
case g x y of g a b -> a
should be equal to, since g x y = y
case y of g a b -> a
but then a could be anything.
If instead it happens that g is defined by an expression which could be a pattern, then GHC can allow using it as a pattern if you ask for it through the PatternSynonyms GHC extension.
pattern G a b = ("hello", b, a)
foo = case someTriple of
G a b -> use a b
(s, x, y) -> ...
bar = G 4 5 -- we can also use G as a function

Why is the type of this function (a -> a) -> a?

Why is the type of this function (a -> a) -> a?
Prelude> let y f = f (y f)
Prelude> :t y
y :: (t -> t) -> t
Shouldn't it be an infinite/recursive type?
I was going to try and put into words what I think it's type should be, but I just can't do it for some reason.
y :: (t -> t) -> ?WTFIsGoingOnOnTheRHS?
I don't get how f (y f) resolves to a value. The following makes a little more sense to me:
Prelude> let y f x = f (y f) x
Prelude> :t y
y :: ((a -> b) -> a -> b) -> a -> b
But it's still ridiculously confusing. What's going on?
Well, y has to be of type (a -> b) -> c, for some a, b and c we don't know yet; after all, it takes a function, f, and applies it to an argument, so it must be a function taking a function.
Since y f = f x (again, for some x), we know that the return type of y must be the return type of f itself. So, we can refine the type of y a bit: it must be (a -> b) -> b for some a and b we don't know yet.
To figure out what a is, we just have to look at the type of the value passed to f. It's y f, which is the expression we're trying to figure out the type of right now. We're saying that the type of y is (a -> b) -> b (for some a, b, etc.), so we can say that this application of y f must be of type b itself.
So, the type of the argument to f is b. Put it all back together, and we get (b -> b) -> b — which is, of course, the same thing as (a -> a) -> a.
Here's a more intuitive, but less precise view of things: we're saying that y f = f (y f), which we can expand to the equivalent y f = f (f (y f)), y f = f (f (f (y f))), and so on. So, we know that we can always apply another f around the whole thing, and since the "whole thing" in question is the result of applying f to an argument, f has to have the type a -> a; and since we just concluded that the whole thing is the result of applying f to an argument, the return type of y must be that of f itself — coming together, again, as (a -> a) -> a.
Just two points to add to other people's answers.
The function you're defining is usually called fix, and it is a fixed-point combinator: a function that computes the fixed point of another function. In mathematics, the fixed point of a function f is an argument x such that f x = x. This already allows you to infer that the type of fix has to be (a -> a) -> a; "function that takes a function from a to a, and returns an a."
You've called your function y, which seems to be after the Y combinator, but this is an inaccurate name: the Y combinator is one specific fixed point combinator, but not the same as the one you've defined here.
I don't get how f (y f) resolves to a value.
Well, the trick is that Haskell is a non-strict (a.k.a. "lazy") language. The calculation of f (y f) can terminate if f doesn't need to evaluate its y f argument in all cases. So, if you're defining factorial (as John L illustrates), fac (y fac) 1 evaluates to 1 without evaluating y fac.
Strict languages can't do this, so in those languages you cannot define a fixed-point combinator in this way. In those languages, the textbook fixed-point combinator is the Y combinator proper.
#ehird's done a good job of explaining the type, so I'd like to show how it can resolve to a value with some examples.
f1 :: Int -> Int
f1 _ = 5
-- expansion of y applied to f1
y f1
f1 (y f1) -- definition of y
5 -- definition of f1 (the argument is ignored)
-- here's an example that uses the argument, a factorial function
fac :: (Int -> Int) -> (Int -> Int)
fac next 1 = 1
fac next n = n * next (n-1)
y fac :: Int -> Int
fac (y fac) -- def. of y
-- at this point, further evaluation requires the next argument
-- so let's try 3
fac (y fac) 3 :: Int
3 * (y fac) 2 -- def. of fac
3 * (fac (y fac) 2) -- def. of y
3 * (2 * (y fac) 1) -- def. of fac
3 * (2 * (fac (y fac) 1) -- def. of y
3 * (2 * 1) -- def. of fac
You can follow the same steps with any function you like to see what will happen. Both of these examples converge to values, but that doesn't always happen.
Let me tell about a combinator. It's called the "fixpoint combinator" and it has the following property:
The Property: the "fixpoint combinator" takes a function f :: (a -> a) and discovers a "fixed point" x :: a of that function such that f x == x. Some implementations of the fixpoint combinator might be better or worse at "discovering", but assuming it terminates, it will produce a fixed point of the input function. Any function that satisfies The Property can be called a "fixpoint combinator".
Call this "fixpoint combinator" y. Based on what we just said, the following are true:
-- as we said, y's input is f :: a -> a, and its output is x :: a, therefore
y :: (a -> a) -> a
-- let x be the fixed point discovered by applying f to y
y f == x -- because y discovers x, a fixed point of f, per The Property
f x == x -- the behavior of a fixed point, per The Property
-- now, per substitution of "x" with "f x" in "y f == x"
y f == f x
-- again, per substitution of "x" with "y f" in the previous line
y f == f (y f)
So there you go. You have defined y in terms of the essential property of the fixpoint combinator:
y f == f (y f). Instead of assuming that y f discovers x, you can assume that x represents a divergent computation, and still come to the same conclusion (iinm).
Since your function satisfies The Property, we can conclude that it is a fixpoint combinator, and that the other properties we have stated, including the type, are applicable to your function.
This isn't exactly a solid proof, but I hope it provides additional insight.

Y Combinator in Haskell

Is it possible to write the Y Combinator in Haskell?
It seems like it would have an infinitely recursive type.
Y :: f -> b -> c
where f :: (f -> b -> c)
or something. Even a simple slightly factored factorial
factMaker _ 0 = 1
factMaker fn n = n * ((fn fn) (n -1)
{- to be called as
(factMaker factMaker) 5
-}
fails with "Occurs check: cannot construct the infinite type: t = t -> t2 -> t1"
(The Y combinator looks like this
(define Y
(lambda (X)
((lambda (procedure)
(X (lambda (arg) ((procedure procedure) arg))))
(lambda (procedure)
(X (lambda (arg) ((procedure procedure) arg)))))))
in scheme)
Or, more succinctly as
(λ (f) ((λ (x) (f (λ (a) ((x x) a))))
(λ (x) (f (λ (a) ((x x) a))))))
For the applicative order
And
(λ (f) ((λ (x) (f (x x)))
(λ (x) (f (x x)))))
Which is just a eta contraction away for the lazy version.
If you prefer short variable names.
Here's a non-recursive definition of the y-combinator in haskell:
newtype Mu a = Mu (Mu a -> a)
y f = (\h -> h $ Mu h) (\x -> f . (\(Mu g) -> g) x $ x)
hat tip
The Y combinator can't be typed using Hindley-Milner types, the polymorphic lambda calculus on which Haskell's type system is based. You can prove this by appeal to the rules of the type system.
I don't know if it's possible to type the Y combinator by giving it a higher-rank type. It would surprise me, but I don't have a proof that it's not possible. (The key would be to identify a suitably polymorphic type for the lambda-bound x.)
If you want a fixed-point operator in Haskell, you can define one very easily because in Haskell, let-binding has fixed-point semantics:
fix :: (a -> a) -> a
fix f = f (fix f)
You can use this in the usual way to define functions and even some finite or infinite data structures.
It is also possible to use functions on recursive types to implement fixed points.
If you're interested in programming with fixed points, you want to read Bruce McAdam's technical report That About Wraps it Up.
The canonical definition of the Y combinator is as follows:
y = \f -> (\x -> f (x x)) (\x -> f (x x))
But it doesn't type check in Haskell because of the x x, since it would require an infinite type:
x :: a -> b -- x is a function
x :: a -- x is applied to x
--------------------------------
a = a -> b -- infinite type
If the type system were to allow such recursive types, it would make type checking undecidable (prone to infinite loops).
But the Y combinator will work if you force it to typecheck, e.g. by using unsafeCoerce :: a -> b:
import Unsafe.Coerce
y :: (a -> a) -> a
y = \f -> (\x -> f (unsafeCoerce x x)) (\x -> f (unsafeCoerce x x))
main = putStrLn $ y ("circular reasoning works because " ++)
This is unsafe (obviously). rampion's answer demonstrates a safer way to write a fixpoint combinator in Haskell without using recursion.
Oh
this wiki page and
This Stack Overflow answer seem to answer my question.
I will write up more of an explanation later.
Now, I've found something interesting about that Mu type. Consider S = Mu Bool.
data S = S (S -> Bool)
If one treats S as a set and that equals sign as isomorphism, then the equation becomes
S ⇋ S -> Bool ⇋ Powerset(S)
So S is the set of sets that are isomorphic to their powerset!
But we know from Cantor's diagonal argument that the cardinality of Powerset(S) is always strictly greater than the cardinality of S, so they are never isomorphic.
I think this is why you can now define a fixed point operator, even though you can't without one.
Just to make rampion's code more readable:
-- Mu :: (Mu a -> a) -> Mu a
newtype Mu a = Mu (Mu a -> a)
w :: (Mu a -> a) -> a
w h = h (Mu h)
y :: (a -> a) -> a
y f = w (\(Mu x) -> f (w x))
-- y f = f . y f
in which w stands for the omega combinator w = \x -> x x, and y stands for the y combinator y = \f -> w . (f w).

Resources