Haskell is evaluating much faster then I thought it would (no complaints) - haskell

I wrote the following to check if a number is prime:
factorsOf :: Int -> [Int]
factorsOf n = [factor | factor <- [2..sqrtOfN], n `rem` factor == 0]
where sqrtOfN = round . sqrt $ fromIntegral $ n+1
isPrime :: Int -> Bool
isPrime n
| factorsOf n == [] = True
| otherwise = False
and it works, but I noticed something weird. If I run factorsOf on a large number (say 100000001), it takes a few seconds to calculate all the factors. If I run isPrime on the same number though, it will return almost immediately if it finds a factor. Does Haskell actually keep track of the condition that a function will return to to support (I'm assuming) lazy evaluation? Thats awesome if it's true.

As noted in the comments, isPrime only needs to evaluate the result of factorsOf deeply enough to determine if it is an empty list or not. You could write isPrime more idiomatically like this:
isPrime = null . factorsOf
where null is simply
null (_:_) = False
null _ = True
Note that as soon as null can pattern match on a (:) constructor, it returns a result without evaluating the rest of the list.
This means only the factorsOf only needs to compute the first factor for isPrime to return, whereas factorsOf by itself will compute the entire list.

The basic principle of laziness is that nothing is evaluated unless it is really really needed. Really needed in your case means that the first function must return so that the other function gets its input. You can read more about Haskell's Laziness here

Related

Prime Factoring Function in Haskell

I am trying to make a function that will display a number's prime factors with a list (infinite) that I give it. Here is what I have so far:
-- Here is a much more efficient (but harder to understand) version of primes.
-- Try "take 100 primes" as an example (or even more if you like)
primes = 2 : primesFrom3 where
primesFrom3 = sieve [3,5..] 9 primesFrom3
sieve (x:xs) b ~ps#(p:q:_)
| x < b = x : sieve xs b ps
| otherwise = sieve [x | x <- xs, rem x p /= 0] (q^2) (tail ps)
-- Write a function that factors its first argument using the (infinite)
-- list of available factors given in its second argument
-- (using rem x p /= 0 to check divisibility)
primeFactsWith :: Integer -> [Integer] -> [Integer]
primeFactsWith n (p:ps) = if (rem n p /= 0) then
(primeFactsWith n ps)
else (primeFactsWith p ps)
The top half was not written by me and works just fine. I am trying to get the second half to work, but it isn't. Read the comments in the code to better understand exactly what I am trying to do. Thanks! Oh and please don't just spout the answer. Give me some hints on how to do it and maybe what is wrong.
What's wrong
The problem is that you do a recursive call in both branches, therefore the function will never stop.
Some Hints
To build a recursive list-producing function, you'll need two branches or cases:
Base case no recursive call, this stops the recursion and returns the final part of the result.
Recursive case here you modify the parameters of the function and call it again with the modified parameters, possibly also returning a part of the result.
You need two sub branches at the recursive branch. One if you've found a prime factor, and another if the current number is no prime factor.
Here is a skeleton, you need to fill in the parts in the <> brackets.
primeFactsWith :: Integer -> [Integer] -> [Integer]
primeFactsWith n (p:ps) = if <halt condition> then
<final result>
else if (rem n p /= 0) then
<not a factor - recursive call 1>
else
<found a factor - return it,
and make recursive call 2>
If you have found a prime factor, you can divide the number by it, to get a smaller number, without that factor. To perform integer division Haskell provides a function named div.
If you reach the number 1, you have generated all prime factors and you can stop. The final part of a prime factors list, that comes after all its factors, is an empty list.
You can drop any prime from your infinite list if you no longer need it, but be aware that a number could contain a prime several times in the factors list. If you want to drop p you can just use ps, from the pattern; if you want to keep p you must use (p:ps).
The cons operator (:) can be used to build a list. You can use it to return one number of the result list, and use a recursive call to find the remaining numbers, e.g.
x : foo y z
I hope that helps, if you have any questions don't hesitate to ask.
Here's a hint.
So you're recursing, which is good.
In one branch you keep looking for factors of n. In the other branch you seem to look for the factors of p, which is a bit weird, but whatevs.
Where do you return the factors of n you've found?

Programming style in OCaml

I have a question about the correct way to write efficient functional programs. Suppose I'm given a list s of positive ints, and I want to find the minimum element (or just 0 if empty). Then a generic functional program for doing this would look like
minList s =
| [] -> undefined
| [x] -> x
| x :: t -> min x (minList t)
In a lazy language one can make this more efficient by adding an extra clause which terminates the recursion if a zero is found - this way s is only computed up to the first zero
minList s =
| [] -> undefined
| [x] -> x
| x :: t -> if x==0 then 0 else min x (minList t)
However, am I correct in believing that this sort of trick would not work in a strict evaluation language like OCaml, which would evaluate the whole of s before running minList? If so, what would be the correct way to optimize this in OCaml?
ADDITIONAL QUESTION: Ok, so if I understand that if statements are always lazy. But what about the following, for example: I have a function on int lists again which first checks whether or not the ith element is zero i.e.
f s = if s(i)==0 then 0 else g s
Here the input sequence s is present in both clauses of the if statement, but clearly for an efficient computation you would only want to evaluate s(i) in the first case. Here, would OCaml always evaluate all of s, even if the first case succeeds?
if expressions in ocaml don't follow the strict evaluation rule.
Like || and &&, it's lazily evaluated.
See this link: if expressions
In a strictly evaluated language, the whole list s would be evaluated. Still,
minList s =
| [] -> 0
| x :: t -> if x==0 then 0 else min x (minList t)
would not scan the whole list if a 0 is found.
The if construct has a "non-strict" semantics, in that it will evaluate only one branch, and not both. This holds in both strict and non strict languages.
An actual difference would be when calling a "user defined if" such as (using Haskell syntax):
myIf :: Bool -> a -> a
myIf b x y = if b then x else y
In a non strict language, calling myIf True 3 (nonTerminatingFunction ()) would yield 3, while in a strict language the same expression would loop forever.
First of all the minimum of an empty list is undefined, not 0. This makes sense, otherwise minList [1,2,3] would be 0 which is clearly not true. This is what ghci has to say:
Prelude> minimum []
*** Exception: Prelude.minimum: empty list
Hence your function should be written as:
let minList (x::t) = min x (minList t)
There are some problems with this definition though:
It will still give an error because there's no pattern match for the empty list.
It is not tail recursive.
It doesn't stop if the head is 0.
So here's a better solution:
let minimum x xs = match x,xs
| 0,xs -> 0
| x,[] -> x
| x,(y :: ys) -> minimum (min x y) ys
let minList = function
| [] -> raise Failure "No minimum of empty list"
| x::t -> minimum x t
The advantage of writing it like this is that minimum is tail recursive. Hence it will not increase the stack size. In addition if the head is 0 it will immediately return 0.
Lazy evaluation has no play here.
In almost every modern programming language:
for expr1 && expr2, if expr1 is already false, then expr2 won't be evaluated.
for expr1 || expr2, if expr1 is already true, then expr2 won't be evaluated.
OCaml does this too.

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.

How can I replace generators if I need only one result?

I'm playing with Haskell for first time.
I've created function that returns first precise enough result. It works as expected, but I'm using generator for this. How can I replace generator in this task?
integrateWithPrecision precision =
(take 1 $ preciseIntegrals precision) !! 0
preciseIntegrals :: Double -> [Double]
preciseIntegrals precision =
[
integrate (2 ^ power) pi | power <- [0..],
enoughPowerForPrecision power precision
]
You can use the beautiful until function. Here it is:
-- | #'until' p f# yields the result of applying #f# until #p# holds.
until :: (a -> Bool) -> (a -> a) -> a -> a
until p f x | p x = x
| otherwise = until p f (f x)
So, you can write your function like this:
integrateWithPrecision precision = integrate (2 ^ pow) pi
where
pow = until done succ 0
done pow = enoughPowerForPrecision pow precision
In your case, you do all the iteration and then compute a result just once. But until is useful even when you need to compute a result at each step - just use an (iter, result) tuple and then just extract the result at the end with snd.
It seems like you want to check higher and higher powers until you get one that satisfies a requirement. This is what you could do: First you define a function to get enough power, and then you integrate using that.
find gets the first element of a list that satisfies a condition – like being enough of a power! Then we need a fromJust to get the actual value from that. Please note that almost always, fromJust is a terrible idea to have in your code. However, in this case the list is infinite, so we will have troubles with infinite loops long before fromJust is able to crash the program.
enoughPower :: Double -> Int
enoughPower precision =
fromJust $ find (flip enoughPowerForPrecision precision) [0..]
preciseIntegrals :: Double -> Double
preciseIntegrals precision = integrate (2^(enoughPower precision)) pi
The function
\xs -> take 1 xs !! 0
is called head
head [] = error "Cannot take head of empty list"
head (x:xs) = x
Its use is somewhat unsafe, as shown it can throw an error if you pass it an empty list, but in this case since you can be certain your list is non-empty it's fine.
Also, we tend not to call these "generators" in Haskell as they're not a special form but are instead a simple consequence of lazy evaluation. In this case, preciseIntegrals is called a "list comprehension" and [0..] is nothing more than a lazily generated list.

Project euler problem 3 in haskell

I'm new in Haskell and try to solve 3 problem from http://projecteuler.net/.
The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143 ?
My solution:
import Data.List
getD :: Int -> Int
getD x =
-- find deviders
let deriveList = filter (\y -> (x `mod` y) == 0) [1 .. x]
filteredList = filter isSimpleNumber deriveList
in maximum filteredList
-- Check is nmber simple
isSimpleNumber :: Int -> Bool
isSimpleNumber x = let deriveList = map (\y -> (x `mod` y)) [1 .. x]
filterLength = length ( filter (\z -> z == 0) deriveList)
in
case filterLength of
2 -> True
_ -> False
I try to run for example:
getD 13195
> 29
But when i try:
getD 600851475143
I get error Exception: Prelude.maximum: empty list Why?
Thank you #Barry Brown, I think i must use:
getD :: Integer -> Integer
But i get error:
Couldn't match expected type `Int' with actual type `Integer'
Expected type: [Int]
Actual type: [Integer]
In the second argument of `filter', namely `deriveList'
In the expression: filter isSimpleNumber deriveList
Thank you.
Your type signature limits the integer values to about 2^29. Try changing Int to Integer.
Edit:
I see that you already realised that you need to use Integer instead of Int. You need to change the types of both getD and isSimpleNumber otherwise you will get a type mismatch.
Also in general, if you are having trouble with types, simply remove the type declarations and let Haskell tell you the correct types.
Main> :t getD
getD :: Integral a => a -> a
Main> :t isSimpleNumber
isSimpleNumber :: Integral a => a -> Bool
After you found the error, may I point out that your solution is quite verbose? In this case a very simple implementation using brute force is good enough:
getD n = getD' n 2 where
getD' n f | n == f = f
| n `mod` f == 0 = getD' (n `div` f) f
| otherwise = getD' n (succ f)
this question is easy enough for brute-force solution, but it is a bad idea to do so because the whole idea of project euler is problems you need to really think of to solve (see end of answer)
so here are some of your program's flaws:
first, use rem instead of mod. it is more efficient.
some mathematical thinking should have told you that you don't need to check all numbers from 1 to x in the isprime function and the getD function, but checking all numbers from the squareroot to one (or reversed) should be sufficient. note that in getD you will actually need to filter numbers between x and the square root, because you search for the biggest one.
why do you use the maximum function in getD? you know the list is monotonically growing, so you may as well get the last one.
despite you only need the biggest divisor (which is prime) you compute the divisors list from small to big making the computer check for each value if it is a divisor or not although discarding the result once a bigger divisor is found. it should be fixed by filtering the list of numbers from x to 1, not from 1 to x. this will cause the computer to check divisibility (how should I say that?) for the biggest possible divisor, not throwing to the trash the knowledge of previous checks. note that this optimization takes effect only if the previous point is optimized, because otherwise the computer will compute all divisors anyway.
with the previous points mixed, you should have filtered all numbers [x,x-1 .. squareroot x] and taken the first.
you don't use an efficient isPrime function. if I were you, I would have searched for an isprime library function, which is guaranteed to be efficient.
and there are more..
with this kind of code you will never be able to solve harder project euler problems. they are designed to need extra thinking about the problem (for instance noticing you don't have to check numbers greater from the square root) and writing fast and efficient code. this is the purpose of project euler; being smart about programming. so don't skip it.

Resources