Changing order of expression evaluation on each function call in Haskell - haskell

Suppose I have a following program:
foo x y = let l1 = foo 0 x
l2 = foo 0 y
in l1 + l2
This is just a simple example, but I think is enough for demonstration purposes. How could I, with each new (recursive) call to foo, change the evaluation ordering of the expression in l1 and l2? I know they are evaluated lazy inside the expression (in this case expression inside in operator) and not when they are declared, but I need a way of doing as stated, because there may be cases, where the program enters infinite loop. If this infinite recursion occurs on the secondly evaluated argument, l2, there is no problem, as l1 always gets evaluated before *l2, but if it is the other way around, that is, infinitely evaluating the l1 expression, the *l2***doesn't get a chance to evaluate. So if I could juggle between ***l1* and l2 expression evaluation on each new foo function call, the problem would be solved. Looking for a nice/general solution.
EDIT: Forgot to mantion that x or y or both might be an infinite structures (lists), and thats where the problem is.

The Problem
For a good answer, we first need a specific question. Consider that natural numbers that are either zero Z or the successor S n of another natural number n.
data Nat = Z | S Nat
zero = Z
one = S Z
two = S $ S Z
In Haskell we can also write infinite recusive data structures like
infinity = S infinity
As long as a single Nat number isn't infinity we can determine if it is even or odd.
even :: Nat -> Bool
even Z = True
even (S n) = odd n
odd :: Nat -> Bool
odd Z = False
odd (S n) = even n
For finite Nats, even is either True or False and even infinity is undefined. This is ok, but what if we wanted to check if either of two numbers is even? We can write a naïve implementation:
eitherEven :: Nat -> Nat -> Bool
eitherEven x y = even x || even y
This does quite well whenever the first argument is finite. In the following, even is any even number and odd is any odd number.
eitherEven even even == True
eitherEven even odd == True
eitherEven even infinity == True
eitherEven odd even == True
eitherEven odd odd == False
eitherEven odd infinity == undefined
But when the first argument is infinite, it doesn't return True even when the second argument is Even
eitherEven infinity even == undefined -- this should be True
eitherEven infinity odd == undefined
eitherEven infinity infinity == undefined
A simple solution
A simple solution to the problem is to alternate between testing the first argument and testing the second argument. When we call the function recursively, we swap the arguments to alternate which of the two arguments is being tested.
eitherEven :: Nat -> Nat -> Bool
eitherEven Z _ = True
eitherEven (S Z) y = even y
eitherEven (S (S x)) y = eitherEven y x
This has the desired output even when the first argument isn't finite.
> eitherEven infinity two
True
For more complicated problems where the arguments aren't treated symmetrically, you can pass a Bool flag and flip it on each step. In general you can use any state machine to keep track of where you are working.
This solution isn't very satisfying because it doesn't immediately solve what to do when we want to test if any of three numbers is even. To do so we need to write a new function.
anyEven3 :: Nat -> Nat -> Nat -> Bool
anyEven3 Z _ _ = True
anyEven3 (S Z) y z = eitherEven y z
anyEven3 (S (S x)) y z = anyEven3 y z x
We put x at the end because we want to try both y and z before trying x again. We're making a queue. If we can prove that the first thing in the queue produces a result, True, we are done. If we can prove the first thing in the queue doesn't produce a result, we remove it from the queue and use a version that works on a smaller set of inputs. If we can't decide the result for the first thing in the queue, we put it at the end. The same pattern can be seen in eitherEven which takes two arguments and even in even which takes only one argument.
anyEven :: [Nat] -> Bool
anyEven = go []
where
go [] [] = False
go r [] = go [] (reverse r)
go r ( Z :_ ) = True
go r ( S Z :ns) = go r ns
go r ((S (S x)):ns) = go (x:r) ns

Related

Function with strict arguments

A corrected quiz in my textbook is asking me how many of f's arguments are strict, f being:
f x 0 z = x == z
f x y z = x
My initial thought was that all of f's arguments are to be considered strict, since y is being evaluated to check if its equal to 0, and x and z are compared to see that they're both equal.
And yet the answer is that only x and y are strict.
Any clues as to why?
First of all, you need a very precise definition of "strict" in order for this to make sense. A function f is strict iff evaluating f x to whnf causes x to be evaluated to whnf. The interaction this has with currying is a bit awkward, and I'm going to ignore some of the potential weirdness that introduces.
Assuming the type here is f :: Bool -> Int -> Bool -> Bool your analysis of the behavior wrt y is correct - evaluating f x y z to whnf will always require evaluating y to determine which equation to choose. As that is the only factor determining which equation to use, we have to split the analysis for x and z. In the first equation, evaluating the result to whnf results in both x and z being evaluated. In the second equation, evaluating the result to whnf results in evaluating x to whnf.
Since x is evaluated in both branches, this function is strict in x. This is a little bit amusing - it's strict in the way id is strict. But that's still valid! z, however, is a different story. Only one of the branches causes z to be evaluated, so it's not evaluated strictly - it's only evaluated on demand. Usually we talk about this happening where evaluation is guarded behind a constructor or when a function is applied and the result isn't evaluated, but being conditionally evaluated is sufficient. f True 1 undefined evaluates to True. If f was strict in z, that would have to evaluate to undefined.
It turns out that whether f is strict in its second argument depends on what type it gets resolved to.
Here's proof:
data ModOne = Zero
instance Eq ModOne where
_ == _ = True -- after all, they're both Zero, right?
instance Num ModOne -- the method implementations literally don't matter
f x 0 z = x == z
f x y z = x
Now in ghci:
> f True (undefined :: ModOne) True
True
> f True (undefined :: Int) True
*** Exception: Prelude.undefined
And, in a related way, whether f is strict in its third argument depends on what values you pick for the first two. Proof, again:
> f True 1 undefined
True
> f True 0 undefined
*** Exception: Prelude.undefined
So, there isn't really a simple answer to this question! f is definitely strict in its first argument; but the other two are conditionally one or the other depending on circumstances.

Couldn't match expected type ‘[Char]’ with actual type ‘Int -> [t -> t1]’

So I'm trying to create a helper function that does something else, but I can't even get past the helper function because I keep getting this error:
Couldn't match expected type ‘[Char]’ with actual type ‘Int -> [t -> t1]’
freqsHelper x = freqs (x (lowers x))
^
The lowers(x) is causing the issue. Here is my code:
lowers [] = 0
lowers (x:xs)
| isLower x == True = 1 + lowers xs
| otherwise = lowers xs
count _ [] = 0
count x (y:ys)
| x == y = 1 + count x ys
| otherwise = count x ys
percent x y = x/y*100
freqsHelper x = freqs (x (lowers x))
freqs (x:xs) y = percent ((count (x (x:xs))) y) : freqs xs y
You’d be well-advised to add type declarations for every top-level function. Let’s follow what the type deduction system is doing here when it tries to figure this out.
The problem is not with lowers, which takes a [Char] as its argument and returns an Int.
The freqsHelper x declaration has one argument, x, whose type we’ll call a while we try to figure it out. We’ll call the return type b. So, freqsHelper is a function of type a -> b.
It’s also equal to freqs (x (lowers x)). So, x, which has type a, must be a function which takes the result of lowers as its argument. We know that lowers is [Char] -> Int, so a must be a function of type Int -> t1, where t1 is some type we would need to deduce from freqs. However, x is also passed as the argument of lowers. Which expects [Char], not a function with one argument. So we already have a contradiction.
So, there’s your mismatch. In the definition of freqsHelper, you’re using x in a context where Haskell expects a string, but also in a context where x has to be some kind of function. I’m pretty sure there’s a bug in freqs as well, given that it calls a function of two numeric arguments with only one argument.
Ah, I think I know what you're getting at. You're close. A couple things - if you're gonna do a division, you should do a fromIntegral to get back some kind of fractional.
percent :: (Fractional a) => Int -> Int -> a
percent x y = (fromIntegral x / fromIntegral y) * 100
I think your frequency is trying to get the frequency of something in a list, in which case you'll need a base case:
freqs [] y = []
freqs (x:xs) y = percent (count x y) (length y) : freqs xs y
I think you can figure out the rest from here.
A few style hints - you can use a map for freqs:
freqs' x y = map (\a -> percent (count a y) $ length y) x
The compiler will probably do it for you, but you can explicitly call out length y:
freqs' x y = map (\a -> percent (count a y) len) x
where len = length y
freqsHelper x = freqs (x (lowers x))
Let's break this down.
lowers x
You call lowers with x as input, so x must be a string.
x (lowers x)
But you call x as a function, passing it the result of lowers as input. So x must be a function that takes an Int as input. (That sounds like a mistake...)
freqs (x (lowers x))
You call freqs with the output from calling the x function... so x must return a list of some kind?
At this point, the type checker is confused as to what the heck x is even supposed to be, so it gives up.
Perhaps you meant to pass x and lowers x as two separate arguments? In that case, you want
freqs x (lowers x)
By putting brackets around x (lowers x), you make the compiler think that x is a function you want to call, with lowers x as the argument. I doubt you meant to do that.
As a side note, if you add type signatures on each of the functions you've defined, you may get a clearer indication from the type checker as to which bit is actually wrong. (As it is, the type checker can see the types don't line up, but can't actually determine where the types deviate from what you intended — because it cannot read your mind to know what you intended...)

Haskell pattern-matching idiom

I'm making a calculator on abstract integers and I'm doing an awful lot of pattern matching. I can write
add Zero x = x
add (P x) y = next $ add (prev $ P x) y
add (N x) y = prev $ add (next $ N x) y
or
add Zero x = x
add x y = case x of
P _ -> next $ add (prev x) y
_ -> prev $ add (next x) y
While the first way is shorter, something in the second way appeals to me more.
Which is the preferred way to do this?
Use as-patterns.
add Zero y = y
add x#(P _) y = next $ add (prev x) y
add x#(N _) y = prev $ add (next x) y
I'd also consider abstracting out the common structure of your two recursive branches by noting that you just swap the roles of the prev and next functions depending on whether x is positive or negative:
add Zero x = x
add x y = f $ add (g x) y
where (f, g) = case x of
P _ -> (next, prev)
N _ -> (prev, next)
About this style:
add Zero x = x
add x y = case x of
P _ -> next $ add (prev x) y
_ -> prev $ add (next x) y
On the positive side, it avoids some repetition, which is good.
On the negative side, the case looks to be non-exhaustive at a first sight. Indeed, to convince oneself that the pattern match is really exhaustive, we have to reason about the possible values for the x in case x of, and see that at runtime that can not be Zero, because that was handled above. This requires far more mental effort than the first snippet, which is obviously exhaustive.
Worse, when turning on warnings, as we should always do, GHC complains since it is not convinced that the case is exhaustive.
Personally, I wish the designers of Haskell had forbidden non exhaustive matches entirely. I'd use a -Werror-on-non-exhaustive-matches if there were one. I would like to be forced to write e.g.
case something of
A -> ...
B -> ...
_ -> error "the impossible happened"
than having the last branch being silently inserted by the compiler for me.
Consider using the math-style definition of integers as congruence classes of pairs of naturals under the equivalence relation:
{((a,b), (c,d)) | b+c == d+a}
The intuition is that the pair of naturals (a,b) represents b-a. As mentioned in the Wikipedia article, this often reduces the number of special cases compared to the "0/positive/negative" definition. In particular, the addition operation you ask about implementing becomes a one-liner:
-- both Int and Integer are taken
data Int' = Int Nat Nat
instance Num Int' where
-- b-a + d-c = (b+d)-(a+c)
Int a b + Int c d = Int (a + c) (b + d)
It's kind of fun to work through the different operations with this representation. For example, Eq can be implemented with the equation given above, and Ord is similar:
instance Eq Int' where
-- b-a == d-c = b+c == d+a
Int a b == Int c d = b+c == d+a
instance Ord Int' where
-- compare (b-a) (d-c) = compare (b+c) (d+a)
compare (Int a b) (Int c d) = compare (b+c) (d+a)
On occasion, it can be handy to normalize these things. Just like fractions can be reduced by multiplying the numerator and denominator by the same number until they're relatively prime, these things can be reduced by adding or subtracting the same number to both parts until (at least) one of them is zero.
normalize (Int (S a) (S b)) = normalize (Int a b)
normalize v = v

Prime number program in haskell

I was looking up a program in Haskell that tests if a given number is prime or not.
prime :: (Integral a) => a -> Bool
prime 1 = True
prime x = and [ x `mod` y /= 0 | y <- [2..(x-1)] ]
I don't understand what is the purpose of this and in: prime x = and [.
Although this question has been answered, please allow me to add a few things:
When examining the source of and, you get:
and :: [Bool] -> Bool
and = foldr (&&) True
First thing to notice is that and takes a list of Boolean variables, and returns a single Boolean variable, and that the expression x mod y /= 0 evaluates to True or False (Hence fitting the [Bool] requirement) .
More important to notice is that foldr is a lazy-fold. So a lazy fold here is optimal because && is a semi-strict operator. Hence a lazy fold in combination with a semi-strict operator will yield a short-circuit evaluation upon encountering the first occurence of a False. Hence in the cases of actual non-prime numbers, and will avoid evaluating the entire list, consequently saving you time as a result. Don't take my word for it, define your own strict version of and if you want (using the stricter foldl):
andStrict :: [Bool] -> Bool
andStrict x = foldl (&&) True
primeStrict :: (Integral a) => a -> Bool
primeStrict x = andStrict [x `mod` y /= 0 | y <- [2..(x-1)]]
Now run:
prime 2000000000
Notice how that was fast? Now do this, but interrupt it before it crashes your memory-stack:
primeStrict 2000000000
That was obviously slower, you were able to interrupt it. This is the role of and, and that is why and was written with foldr, and hence why it was chosen for the example code you posted. Hope that helps as a supportive answer.
The expression
[x `mod` y /= 0 | y <- [2..(x - 1)]
is a list of Bools because mod x y /= 0 (prefix notation because of backtick formatting) returns a Bool. The and function just does a logical AND of every element in a list, so
and [True, False] == False
and [True, True] == True
and performs a logical and operation on all elements of a list.
Primes are only divisible by one and themselves; this means that as soon as a divisor (without a remainder) exists between 2 inclusive and your x exclusive, the number is not a prime.
The list comprehension generates a list of Boolean values that correspond to whether your x is or is not divisible by numbers from within the said range.
As soon as any of them is false (a division occurred with a zero remainder), the number is not a prime.
Consider:
x = 7
[7 % 2 /= 0 -> True, 7 % 3 /= -> True, ...]
-- now applying and
True && True && ... && True evaluates to True
and can be represented as a more general operation that can be performed on lists - a fold using logical and. Such as: and' = foldr (&&) True.

If I have an expression, which is partitially evaluable, is it a good idea to avoid tail-recursion?

Consider an haskell-expression like the following: (Trivial example, don't tell me what the obvious way is! ;)
toBits :: Integral a => a -> [Bool]
toBits 0 = []
toBits n = x : toBits m where
(m,y) = n `divMod` 2
x = y /= 0
Because this function is not tail-recursive, one could also write:
toBits :: Integral a => a -> [Bool]
toBits = toBits' [] where
toBits' l 0 = l
toBits' l n = toBits (x : l) m where
(m,y) = n `divMod` 2
x = y /= 0
(I hope there is nothing wron whithin this expression)
What I want to ask is, which one of these solutions is better. The advantage of the first one is, that it can be evaluated partitially very easy (because Haskell stops at the first : not needed.), but the second solution is (obviously) tail-recursive, but in my opinion it needs to be completely evaluated until you can get something out.
The background for this is my Brainfuck parser, (see my optimization question), which is implemented very uggly (various reverse instructions... ooh), but can be implemented easily in the first - let's call it "semi-tail-recursion" way.
I think you've got it all just right. The first form is in general better because useful output can be obtained from it before it has completed computation. That means that if 'toBits' is used in another computation the compiler can likely combine them and the list that is the output of 'toBits' may never exist at all, or perhaps just one cons cell at a time. Nice that the first version is also more clear to read!
In Haskell, your first choice would typically be preferred (I would say "always," but you're always wrong when you use that word). The accumulator pattern is appropriate for when the output can not be consumed incrementally (e.g. incrementing a counter).
Let me rename the second version and fix a few typos so that you can test the functions.
toBits :: Integral a => a -> [Bool]
toBits 0 = []
toBits n = x : toBits m where
(m,y) = n `divMod` 2
x = y /= 0
toBits2 :: Integral a => a -> [Bool]
toBits2 = toBits' [] where
toBits' l 0 = l
toBits' l n = toBits' (x : l) m where
(m,y) = n `divMod` 2
x = y /= 0
These functions don't actually compute the same thing; the first one produces a list starting with the least significant bit, while the second one starts with the most significant bit. In other words toBits2 = reverse . toBits, and in fact reverse can be implemented with exactly the same kind of accumulator that you use in toBits2.
If you want a list starting from the least significant bit, toBits is good Haskell style. It won't produce a stack overflow because the recursive call is contained inside the (:) constructor which is lazy. (Also, you can't cause a thunk buildup in the argument of toBits by forcing the value of a late element of the result list early, because the argument needs to be evaluated in the first case toBits 0 = [] to determine whether the list is empty.)
If you want a list starting from the most significant bit, either writing toBits2 directly or defining toBits and using reverse . toBits is acceptable. I would probably prefer the latter since it's easier to understand in my opinion and you don't have to worry about whether your reimplementation of reverse will cause a stack overflow.

Resources