How `fix f = let {x = f x} in x` is evaluated? - haskell

fix f = let {x = f x} in x
Talking about let, I thought that let P = Q in R would evaluate Q -> Q' then P is replaced by Q' in R, or: R[P -> Q'].
But in fix definition the Q depends on R, how to evaluate then?
I imagine that this is about lazy evaluation. Q' becomes a thunk, but I can't reason this in my head.
As a matter of context, I'm looking at Y combinator, it should find a fixed point of a function so if I have this function, one x = 1, then fix one == 1 must hold, right?
So fix one = let {x = one x} in x, but I can't see how 1 would emerge from that.

Talking about let, I thought that let P = Q in R would evaluate Q -> Q' then P is replaced by Q' in R, or: R[P -> Q'].
Morally, yes, but P is not immediately evaluated, it is evaluated when needed.
But in fix definition the Q depends on R, how to evaluate then?
Q does not depend on R, it depends on P. This makes P depend on itself, recursively. This can lead to several different outcomes. Roughly put:
If Q can not return any part of its result before evaluating P, then P represents an infinitely recursing computation, which does not terminate. For example,
let x = x + 1 in x -- loops forever with no result
-- (GHC is able to catch this specific case and raise an exception instead,
-- but it's an irrelevant detail)
If Q can instead return a part of its result before needing to evaluate P, it does so.
let x = 2 : x in x
-- x = 2 : .... can be generated immediately
-- This results in the infinite list 2:2:2:2:2:.....
let x = (32, 10 + fst x) in x
-- x = (32, ...) can be generated immediately
-- hence x = (32, 10 + fst (32, ...)) = (32, 10+32) = (32, 42)
I imagine that this is about lazy evaluation. Q' becomes a thunk, but I can't reason this in my head.
P is associated with a thunk. What matters is whether this thunk calls itself before returning some part of the output or not.
As a matter of context, I'm looking at Y combinator, it should find a fixed point of a function so if I have this function. one x = 1, then fix one == 1 must hold, right?
Yes.
So fix one = let x = one x in x, but I can't see why 1 would emerge from that
We can compute it like this:
fix one
= {- definition of fix -}
let x = one x in x
= {- definition of x -}
let x = one x in one x
= {- definition of one -}
let x = one x in 1
= {- x is now irrelevant -}
1
Just expand the definitions. Keep recursive definitions around in case you need them again.

Related

What does one gain when redefining data constructors, and in place of what expressions might such a definition be substituted?

Reading this answer, I'm getting puzzled by the very first code fragment:
data Pair a = P a a
instance Functor Pair where
fmap f (P x y) = P (f x) (f y)
instance Monad Pair where
return x = P x x
P a b >>= f = P x y
where P x _ = f a
P _ y = f b
What I see is the author redefining a data constructor two times and applying it to undefined variables.
First off, how does the second of the two definitions of P (those two that are found in the where clause of the instance Monad definition) matter if, as I believe, the first one (whichever we put first) always matches?
Second, according to what syntax rules could the expression P x y get evaluated when there are no expressions for x and y in scope, but rather some kind of a redefinition of a data constructor that happens to mention these variables' names?
Interesting to note that, if I instead write like:
P a b >>= f = P x y
where P u _ = f a
P _ v = f b
— substituting u & v for x & y
— I will observe an error: Variable not in scope for each of x & y, even though by all sane intuition renaming a bound variable makes no difference.
The equation
P x y = z
does not define P, only x and y. This is the case in general: only the data and newtype keywords can introduce new constructors. All other equations define only term variables. To disambiguate between the two, constructors always begin with upper case (for the special case of operators, : counts as "upper case punctuation") and variables always begin with lower case.
So, the meaning of
P a b >>= f = P x y
where P x _ = f a
P _ y = f b
reads like this:
Define a new function named (>>=). It is defined when the first argument matches the pattern P a b (binding a and b to the actual values P is applied to in the first argument), and when the second argument matches the pattern f (that is, always, and binding f to the value of that second argument).
Apply f to a. Make sure the result of this matches the pattern P x _ (binding x to the first value P is applied to and throwing away the second).
Apply f to b. Make sure the result of this matches the pattern P _ y (binding y to the second value P is applied to and throwing away the first).
Return the value P x y.

Nested "Let" expressions in Ocaml

All:
How can I write the following in the "Curry" syntax:
let y = 2 in
let f x = x + y in
let f x = let y = 3 in f y in
f 5
I at first tried something like this:
(y -> (f -> ((f x -> f 5) (y -> f y) 3)) x + y) 2
However this does not seem evaluate properly.
Even better yet would be a Lambda-expression to see binding.
Thanks!
let v = e1 in e2 translates to lambda calculus as (\v.e2)(e1) (where I use the backslash to denote a lambda). So, your example would be
(\y1.(\f1.(\f2.f2 5)(\x2.(\y2.f1(y2))(3)))(\x1.x1+y1))(2)
I used alpha conversion to differentiate between variables that otherwise would have the same name. Observe that the f in the middle has become f1, that is the f in f y in the third line of your example uses the f defined in the second line, not the one which is about to be defined in the third line. In other words, your definition is not recursive; you have used let, not let rec.
Digression: Translating let rec into the lambda calculus requires a fixed point combinator Y (or some like technique). Y is characterized by the property that Y(f) reduces to f(Y(f)). Then, let rec v = e1 in e2 roughly translates to (\v.e2)(Y(\v.e1)).

Why Haskell disrespects bound identifiers for pattern matching?

f x zero = Nothing
f x y = Just $ x / y
where zero = 0
The literal-bound identifier zero simply matches all after the warning Pattern match(es) are overlapped.
That's how Haskell's syntax works; every lowercase-initial variable name in a pattern (re)binds that name. Any existing binding will be shadowed.
But even if that weren't the case, the binding for zero would not be visible to the first alternative, because of how Haskell's syntax works. A similar thing happens in the following version:
f = \v1 v2 -> case (v1, v2) of
(x, zero) -> Nothing
(x, y) -> Just $ x / y
where zero = 0
The where clause only applies to the one alternative that it's part of, not to the whole list of alternatives. That code is pretty much the same thing as
f = \v1 v2 -> case (v1, v2) of
(x, zero) -> Nothing
(x, y) -> let zero = 0 in Just $ x / y
If bound identifiers had different semantics than unbound identifiers in a pattern match, that could be quite error prone as binding a new identifier could mess up pattern matches anywhere that identifier is in scope.
For example let's say you're importing some module Foo (unqualified). And now the module Foo is changed to add the binding x = 42 for some reason. Now in your pattern match you'd suddenly be comparing the first argument against 42 rather than binding it to x. That's a pretty hard to find bug.
So to avoid this kind of scenario, identifier patterns have the same semantics regardless of whether they're already bound somewhere.
Because they are very fragile. What does this compute?
f x y z = 2*x + 3*y + z
Would you expect this to be equal to
f x 3 z = 2*x + 9 + z
f _ _ _ = error "non-exhaustive patterns!"
only because there's a y = 3 defined somewhere in the same 1000+ line module?
Also consider this:
import SomeLibrary
f x y z = 2*x + 3*y + z
What if in a future release SomeLibrary defines y? We don't want that to suddenly stop working.
Finally, what if there is no Eq instance for y?
y :: a -> a
y = id
f :: a -> (a -> a) -> a
f x y = y x
f x w = w (w x)
Sure, it is a contrived example, but there's no way the runtime can compare the input function to check whether it is equal to y or not.
To disambiguate this, some new languages like Swift uses two different syntaxes. E.g. (pseudo-code)
switch someValue {
case .a(x) : ... // compare by equality using the outer x
case .b(let x) : ... // redefine x as a new local variable, shadowing the outer one
}
zero is just a variable that occurs inside a pattern, just like y does in the second line. There is no difference between the two. When a variable that occurs inside a pattern, this introduces a new variable. If there was a binding for that variable already, the new variable shadows the old one.
So you cannot use an already bound variable inside a pattern. Instead, you should do something like that:
f x y | y == zero = Nothing
where zero = 0
f x y = Just $ x / y
Notice that I also moved the where clause to bring it in scope for the first line.

Is it possible to define patterns of composition in functions or functors?

Consider the following situation. I define a function to process a list of elements by the typical way of doing an operation on the head and recalling the function over the rest of the list. But under certain condition of the element (being negative, being a special character, ...) I change sign on the rest of the list before continuing. Like this:
f [] = []
f (x : xs)
| x >= 0 = g x : f xs
| otherwise = h x : f (opposite xs)
opposite [] = []
opposite (y : ys) = negate y : opposite ys
As opposite (opposite xs) = xs, I become to the situation of redundant opposite operations, accumulating opposite . opposite . opposite ....
It happens with other operations instead of opposite, any such that the composition with itself is the identity, like reverse.
Is it possible to overcome this situation using functors / monads / applicatives / arrows? (I don't understand well those concepts). What I would like is to be able of defining a property, or a composition pattern, like this:
opposite . opposite = id -- or, opposite (opposite y) = y
in order that the compiler or interpreter avoids to calculate the opposite of the opposite (it is possible and simple (native) in some concatenative languages).
You can solve this without any monads, since the logic is quite simple:
f g h = go False where
go _ [] = []
go b (x':xs)
| x >= 0 = g x : go b xs
| otherwise = h x : go (not b) xs
where x = (if b then negate else id) x'
The body of the go function is almost identical to that of your original f function. The only difference is that go decides whether the element should be negated or not based on the boolean value passed to it from previous calls.
Sure, just keep a bit of state telling whether to apply negate to the current element or not. Thus:
f = mapM $ \x_ -> do
x <- gets (\b -> if b then x_ else negate x_)
if x >= 0
then return (g x)
else modify not >> return (h x)

Haskell: Where vs. Let

I am new to Haskell and I am very confused by Where vs. Let. They both seem to provide a similar purpose. I have read a few comparisons between Where vs. Let but I am having trouble discerning when to use each. Could someone please provide some context or perhaps a few examples that demonstrate when to use one over the other?
Where vs. Let
A where clause can only be defined at the level of a function definition. Usually, that is identical to the scope of let definition. The only difference is when guards are being used. The scope of the where clause extends over all guards. In contrast, the scope of a let expression is only the current function clause and guard, if any.
Haskell Cheat Sheet
The Haskell Wiki is very detailed and provides various cases but it uses hypothetical examples. I find its explanations too brief for a beginner.
Advantages of Let:
f :: State s a
f = State $ \x -> y
where y = ... x ...
Control.Monad.State
will not work, because where refers to
the pattern matching f =, where no x
is in scope. In contrast, if you had
started with let, then you wouldn't
have trouble.
Haskell Wiki on Advantages of Let
f :: State s a
f = State $ \x ->
let y = ... x ...
in y
Advantages of Where:
f x
| cond1 x = a
| cond2 x = g a
| otherwise = f (h x a)
where
a = w x
f x
= let a = w x
in case () of
_ | cond1 x = a
| cond2 x = g a
| otherwise = f (h x a)
Declaration vs. Expression
The Haskell wiki mentions that the Where clause is declarative while the Let expression is expressive. Aside from style how do they perform differently?
Declaration style | Expression-style
--------------------------------------+---------------------------------------------
where clause | let expression
arguments LHS: f x = x*x | Lambda abstraction: f = \x -> x*x
Pattern matching: f [] = 0 | case expression: f xs = case xs of [] -> 0
Guards: f [x] | x>0 = 'a' | if expression: f [x] = if x>0 then 'a' else ...
In the first example why is the Let in scope but Where is not?
Is it possible to apply Where to the first example?
Can some apply this to real examples where the variables represent actual expressions?
Is there a general rule of thumb to follow when to use each?
Update
For those that come by this thread later on I found the best explanation to be found here: "A Gentle Introduction to Haskell".
Let Expressions.
Haskell's let expressions are useful
whenever a nested set of bindings is
required. As a simple example,
consider:
let y = a*b
f x = (x+y)/y
in f c + f d
The set of bindings created by a let
expression is mutually recursive, and
pattern bindings are treated as lazy
patterns (i.e. they carry an implicit
~). The only kind of declarations
permitted are type signatures,
function bindings, and pattern
bindings.
Where Clauses.
Sometimes it is convenient to scope
bindings over several guarded
equations, which requires a where
clause:
f x y | y>z = ...
| y==z = ...
| y<z = ...
where z = x*x
Note that this cannot be done with a let expression, which only scopes over the expression which it encloses. A where clause is only allowed at the top level of a set of equations or case expression. The same properties and constraints on bindings in let expressions apply to those in where clauses. These two forms of nested scope seem very similar, but remember that a let expression is an expression, whereas a where clause is not -- it is part of the syntax of function declarations and case expressions.
1: The problem in the example
f :: State s a
f = State $ \x -> y
where y = ... x ...
is the parameter x. Things in the where clause can refer only to the parameters of the function f (there are none) and things in outer scopes.
2: To use a where in the first example, you can introduce a second named function
that takes the x as a parameter, like this:
f = State f'
f' x = y
where y = ... x ...
or like this:
f = State f'
where
f' x = y
where y = ... x ...
3: Here is a complete example without the ...'s:
module StateExample where
data State a s = State (s -> (a, s))
f1 :: State Int (Int, Int)
f1 = State $ \state#(a, b) ->
let
hypot = a^2 + b^2
result = (hypot, state)
in result
f2 :: State Int (Int, Int)
f2 = State f
where
f state#(a, b) = result
where
hypot = a^2 + b^2
result = (hypot, state)
4: When to use let or where is a matter of taste. I use let to emphasize a computation (by moving it to the front) and where to emphasize the program flow (by moving the computation to the back).
While there is the technical difference with respect to guards that ephemient pointed out, there is also a conceptual difference in whether you want to put the main formula upfront with extra variables defined below (where) or whether you want to define everything upfront and put the formula below (let). Each style has a different emphasis and you see both used in math papers, textbooks, etc. Generally, variables that are sufficiently unintuitive that the formula doesn't make sense without them should be defined above; variables that are intuitive due to context or their names should be defined below. For example, in ephemient's hasVowel example, the meaning of vowels is obvious and so it need not be defined above its usage (disregarding the fact that let wouldn't work due to the guard).
Legal:
main = print (1 + (let i = 10 in 2 * i + 1))
Not legal:
main = print (1 + (2 * i + 1 where i = 10))
Legal:
hasVowel [] = False
hasVowel (x:xs)
| x `elem` vowels = True
| otherwise = False
where vowels = "AEIOUaeiou"
Not legal: (unlike ML)
let vowels = "AEIOUaeiou"
in hasVowel = ...
Sadly, most of the answers here are too technical for a beginner.
LHYFGG has a relevant chapter on it -which you should read if you haven't already, but in essence:
where is just a syntactic construct (not a sugar) that are useful only at function definitions.
let ... in is an expression itself, thus you can use them wherever you can put an expression. Being an expression itself, it cannot be used for binding things for guards.
Lastly, you can use let in list comprehensions too:
calcBmis :: (RealFloat a) => [(a, a)] -> [a]
calcBmis xs = [bmi | (w, h) <- xs, let bmi = w / h ^ 2, bmi >= 25.0]
-- w: width
-- h: height
We include a let inside a list comprehension much like we would a predicate, only it doesn't filter the list, it only binds to names. The names defined in a let inside a list comprehension are visible to the output function (the part before the |) and all predicates and sections that come after of the binding. So we could make our function return only the BMIs of people >= 25:
I found this example from LYHFGG helpful:
ghci> 4 * (let a = 9 in a + 1) + 2
42
let is an expression so you can put a let anywhere(!) where expressions can go.
In other words, in the example above it is not possible to use where to simply replace let (without perhaps using some more verbose case expression combined with where).

Resources