Haskell pattern matching inside parentheses - haskell

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

Related

Understanding the flip function

I am learning higher-order functions from 'Learn You a Haskell for Great Good!' by Miran Lipovaca.
For the following function flip which takes a function and returns a function with the first two arguments flipped:
flip' :: (a -> b -> c) -> (b -> a -> c)
flip' f = g
where g x y = f y x
I don't exactly understand what f and g are. Are they two different functions? Similarly, in the where binding, what exactly does g x y = f y x mean?
In the syntax:
myFunction x = x + 2
things on the left hand side of the equal sign, x, are treated as "parameters". You can use them on the right hand sign of the equal sign to state what you want the result to be.
This syntax defines a function myFunction, with single parameter x.
So here we have:
flip' f = g
This defines a function flip', with single parameter f.
We have another definition, as well:
g x y = f y x
This defines a function g, with two parameters, x and y.
So when we say:
flip' f = g
where
g x y = f y x
We are saying that the result of flip f is the function g, where g is defined as g x y = f y x.
In case the short variable names are confusing you, here is the same function with some of the names swapped for clarity:
flippity flop = glop
where
glop x y = flop y x
See if you can understand what flippity does, and see if you can see how it is the same as flip', just with different internal parameter and helper function names.
Remember also in Haskell that we can always replace function calls by their body, for the most part. So we can rewrite that as:
flippity flop = glop
where
glop = \x y -> flop y x
-- replace glop with its definition
flippity flop = \x y -> flop y x
So we can see that flippity is a function that takes a function flop and returns a new function, \x y -> flop y x.
f is flip''s input (the function you want to flip), g is flip's output (the flipped function it will return).
The where clause is simply defining what g is; that is, defining a function that simply calls f with its arguments reversed.
You could avoid naming g at all by simply having flip' return a lambda:
flip' :: (a -> b -> c) -> (b -> a -> c)
flip' f = \x y -> f y x

Syntax of where block

I'm reading Programming in Haskell by Graham Hutton and it gives the following code in Chapter 13:
import Control.Applicative
import Data.Char
{- some code omitted -}
newtype Parser a = P (String -> [(a, String)])
item :: Parser Char
item = P (\ input -> case input of
[] -> []
x:xs -> [(x,xs)])
three :: Parser (Char,Char)
three = pure g <*> item <*> item <*> item
where g a b c = (a,c)
I'm having a hard time understanding the last line
where g a b c = (a,c)
I understand that this line exists because three has type Parser(Char, Char) but what does g a b c represent? How is g a b c syntactically valid? I'm used to seeing where in cases like
f :: s -> (a,s)
f x = y
where y = ... x ...
where each symbol x and y appear before the where declaration.
It is the syntax to declare a function. It is the equivalent to
where g = \a b c -> (a,c)
g is a function which takes 3 arguments and returns a tuple
How is g a b c syntactically valid?
It's valid for the same reason same definition on the top-level of the module would be valid. The difference between definitions in where and top level is just that you have variables bound in function's head (e.g. x in your last example) in scope and can use them on the right side, but this doesn't mean you have to use them.

How does the flip function work?

Haskell newbie here. I was going through Learn you a haskell, and came across this definition of the flip function.
flip' :: (a -> b -> c) -> (b -> a -> c)
flip' f = g
where g x y = f y x
What I don't get is, where did x and y come from? I mean, the signature tells me that flip' is a function that takes a function (with two parameters), and returns a function (again, with two parameters).
If I'm understanding this right, when I write a function which goes like
foo :: (a -> b) -> a -> b
foo f x = f x -- applies the function f on x
But then, in this case I'm passing the parameter explicitly [ ie x ] and so I'm able to access it in the function body. So how come the flip' function can access the parameters x and y?
The Prelude, which is in the base package at hackage.haskell.org, is included with an implicit import in every Haskell file is where the flip function is found. On the right side you can click "source" and see the source code for flip.
flip :: (a -> b -> c) -> b -> a -> c
flip f x y = f y x
The where clause allows for local definitions, x=10 or y="bla". You can also define functions locally with the same syntax you would for the top level. add x y = x + y
In the below equivalent formulation I make the substitution g = f y x
flip :: (a -> b -> c) -> b -> a -> c
flip f x y = g
where
g = f y x
Right now g takes no parameters. But what if we defined g as g a b = f b a well then we would have:
flip :: (a -> b -> c) -> b -> a -> c
flip f x y = g x y
where
g a b = f b a
No we can do a little algebraic cancelation(if you think of it like algebra from math class you will be pretty safe). Focusing in on:
flip f x y = g x y
Cancel the y on each side for:
flip f x = g x
Now cancel the x:
flip f = g
and now to put it back in the full expression:
flip :: (a -> b -> c) -> b -> a -> c
flip f = g
where
g a b = f b a
As a last cosmetic step we can make the substitution a to x and b to y to recover the function down to argument names:
flip :: (a -> b -> c) -> b -> a -> c
flip f = g
where
g x y = f y x
As you can see this definition of flip is a little round about and what we start with in the prelude is simple and is the definition I prefer. Hope that helps explain how where works and how to do a little algebraic manipulation of Haskell code.
flip' doesn't access x and y. It receives an argument f, and evaluates to the expression g. No x or y in sight.
However, g is itself a function, defined with an auxiliary equation in the where clause of flip'.
You can read g x y = f y x exactly as if it were a top level equation like flip'. So g is a function of two arguments, x and y. It's g that has access to x and y, not flip'. Values for those arguments don't exist until g is applied, which is not until after flip' has returned the function g (if ever).
The thing that's special that about g being defined in the where clause of flip' is that it can have access to the arguments of flip', which is how g can be defined in terms of f.
So when flip' is invoked it receives a function f. For each particular invocation of flip', it constructs a new function g. g would receive two arguments, x and y, when it is called, but that hasn't happened yet. flip' then just returns g as its result.
One simple example to understand and illustrate, on your ghci do:
Prelude> sub x y = x - y
Prelude> sub 3 1
2
Prelude> flip sub 3 1
-2
Let's find the type of g.
We know flip type : (a -> b -> c) -> (b -> a -> c)
Therefore we can deduce f type : (a -> b -> c)
We have this definition for g
g x y = f y x
From the right-hand-side we deduce that y :: a and x :: b.
Hence g :: b -> a -> c
Note that the definition could be rewritten without the 'where' clause.
flip' f = g where g x y = f y x
-> flip' f a b = g a b where g a b = f b a
-> flip' f a b = f b a
Put simply, you can also define functions in a where block. So the variables x and y are just the formal parameters of g, and that's why you can access it in g x y = f y x: g x y defines formal parameters x and y, and f y x is the definition of what g does. Finally, that definition is returned from flip f = g.

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.

Writing in pointfree style f x = g x x

I am learning Haskell. I'm sorry for asking a very basic question but I cant seem to find the answer. I have a function f defined by :
f x = g x x
where g is an already defined function of 2 arguments. How do I write this pointfree style?
Edit : without using a lambda expression.
Thanks
f can be written with Control.Monad.join:
f = join g
join on the function monad is one of the primitives used when constructing point-free expressions, as it cannot be defined in a point-free style itself (its SKI calculus equivalent, SII — ap id id in Haskell — doesn't type).
This is known as "W" combinator:
import Control.Monad
import Control.Monad.Instances
import Control.Applicative
f = join g -- = Wg (also, join = (id =<<))
= (g `ap` id) -- \x -> g x (id x) = SgI
= (<*> id) g -- = CSIg
= g =<< id -- \x -> g (id x) x
= id =<< g -- \x -> id (g x) x
S,K,I are one basic set of combinators; B,C,K,W are another - you've got to stop somewhere (re: your "no lambda expression" comment):
_B = (.) -- _B f g x = f (g x) = S(KS)K
_C = flip -- _C f x y = f y x = S(S(K(S(KS)K))S)(KK)
_K = const -- _K x y = x
_W = join -- _W f x = f x x = CSI = SS(KI) = SS(SK)
_S = ap -- _S f g x = f x (g x) = B(B(BW)C)(BB) = B(BW)(BBC)
= (<*>) -- from Control.Applicative
_I = id -- _I x = x = WK = SKK = SKS = SK(...)
{-
Wgx = gxx
= SgIx = CSIgx
= Sg(KIg)x = SS(KI)gx
= gx(Kx(gx)) = gx(SKgx) = Sg(SKg)x = SS(SK)gx
-- _W (,) 5 = (5,5)
-- _S _I _I x = x x = _omega x -- self-application, untypeable
-}
I got here by pure chance, and I want to offer my solution, as nobody has mentioned lifting yet in this thread, not explicitly at least.
This is a solution:
f = liftM2 g id id
How to look at it?
g has type a -> a -> b, i.e. it takes two values of some type (the same type for both, otherwise the definition the OP gave of f wouldn't make sense), and gives back another value of some type (not necessarily of the same type as the arguments);
lift2M g is the lifted version of g and it has type (Monad m) => m a -> m a -> m b: it takes two monadic values, which are each a value in a so-far-unspecified context, and gives back a monadic value;
when passing two functions to liftM2 g, the die is cast on what the context of the Monad is: it is that the values are not in there yet, but will eventually be, when the function will receive the arguments it needs; in other words, functions are monads that store their own future values; therefore, lift2M g takes in input two functions (or, the future values of two functions), and gives back the another function (or, its future value); knowing this, its type is the same as above if you change m to (->) r, or r ->: (r -> a) -> (r -> a) -> (r -> b)
the two functions that we pass are both id, which promises it'll give back the same value it receives;
liftM2 g id id is therefore a function of type r -> b that passes its argument to those two ids, which let it unchanged and forward it to g.
In a similar fashion, one can exploit that functions are applicative functors, and use this solution:
f = g <$> id <*> id

Resources