Unresolved top level overloading - haskell

Task is to find all two-valued numbers representable as the sum of the sqrt's of two natural numbers.
I try this:
func = [sqrt (x) + sqrt (y) | x <- [10..99], y <- [10..99], sqrt (x) `mod` 1 == 0, sqrt (y) `mod` 1 == 0]
Result:
Unresolved top-level overloading Binding : func
Outstanding context : (Integral b, Floating b)
How can I fix this?

This happens because of a conflict between these two types:
sqrt :: Floating a => a -> a
mod :: Integral a => a -> a -> a
Because you write mod (sqrt x) 1, and sqrt is constrained to return the same type as it takes, the compiler is left trying to find a type for x that simultaneously satisfies the Floating constraint of sqrt and the Integral constraint of mod. There are no types in the base library that satisfy both constraints.
A quick fix is to use mod' :: Real a => a -> a -> a:
import Data.Fixed
func = [sqrt (x) + sqrt (y) | x <- [10..99], y <- [10..99], sqrt (x) `mod'` 1 == 0, sqrt (y) `mod'` 1 == 0]
However, from the error you posted, it looks like you may not be using GHC, and mod' is probably a GHC-ism. In that case you could copy the definition (and the definition of the helper function div') from here.
But I recommend a more involved fix. The key observation is that if x = sqrt y, then x*x = y, so we can avoid calling sqrt at all. Instead of iterating over numbers and checking if they have a clean sqrt, we can iterate over square roots; their squares will definitely have clean square roots. A straightforward application of this refactoring might look like this:
sqrts = takeWhile (\n -> n*n <= 99)
. dropWhile (\n -> n*n < 10)
$ [0..]
func = [x + y | x <- sqrts, y <- sqrts]
Of course, func is a terrible name (it's not even a function!), and sqrts is a constant we could compute ourselves, and is so short we should probably just inline it. So we might then simplify to:
numberSums = [x + y | x <- [4..9], y <- [4..9]]
At this point, I would be wondering whether I really wanted to write this at all, preferring just
numberSums = [8..18]
which, unlike the previous iteration, doesn't have any duplicates. It has lost all of the explanatory power of why this is an interesting constant, though, so you would definitely want a comment.
-- sums of pairs of numbers, each of whose squares lies in the range [10..99]
numberSums = [8..18]
This would be my final version.
Also, although the above definitions were not parameterized by the range to search for perfect squares in, all the proposed refactorings can be applied when that is a parameter; I leave this as a good exercise for the reader to check that they have understood each change.

Related

Perplexing behaviour when approximating the derivative in haskell

I have defined a typeclass Differentiable to be implemented by any type which can operate on infinitesimals.
Here is an example:
class Fractional a => Differentiable a where
dif :: (a -> a) -> (a -> a)
difs :: (a -> a) -> [a -> a]
difs = iterate dif
instance Differentiable Double where
dif f x = (f (x + dx) - f(x)) / dx
where dx = 0.000001
func :: Double -> Double
func = exp
I have also defined a simple Double -> Double function to differentiate.
But when I test this in the ghc this happens:
... $ ghci
GHCi, version 8.8.4: https://www.haskell.org/ghc/ :? for help
Prelude> :l testing
[1 of 1] Compiling Main ( testing.hs, interpreted )
Ok, one module loaded.
*Main> :t func
func :: Double -> Double
*Main> derivatives = difs func
*Main> :t derivatives
derivatives :: [Double -> Double]
*Main> terms = map (\f -> f 0) derivatives
*Main> :t terms
terms :: [Double]
*Main> take 5 terms
[1.0,1.0000004999621837,1.000088900582341,-222.0446049250313,4.440892098500626e8]
*Main>
The approximations to the nth derivative of e^x|x=0 are:
[1.0,1.0000004999621837,1.000088900582341,-222.0446049250313,4.440892098500626e8]
The first and 2nd derivatives are perfectly reasonable approximations given the setup, but suddenly, the third derivative of func at 0 is... -222.0446049250313! HOW!!?
The method you're using here is a finite difference method of 1st-order accuracy.
Layman's translation: it works, but is pretty rubbish numerically speaking. Specifically, because it's only 1st-order accurate, you need those really small steps to get good accuracy even with exact-real-arithmetic. You did choose a small step size so that's fine, but small step size brings in another problem: rounding errors. You need to take the difference f (x+δx) - f x with small δx, meaning the difference is small whereas the individual values may be large. That always brings up the floating-point inaccuracy – consider for example
Prelude> (1 + pi*1e-13) - 1
3.141931159689193e-13
That might not actually hurt that much, but since you then need to divide by δx you boost up the error.
This issue just gets worse/compounded as you go to the higher derivatives, because now each of the f' x and f' (x+δx) has already an (non-identical!) boosted error on it, so taking the difference and boosting again is a clear recipe for disaster.
The simplest way to remediate the problem is to switch to a 2nd-order accurate method, the obvious being central difference. Then you can make the step a lot bigger, and thus largely avoid rounding issues:
Prelude> let dif f x = (f (x + δx) - f(x - δx)) / (2*δx) where δx = 1e-3
Prelude> take 8 $ ($0) <$> iterate dif exp
[1.0,1.0000001666666813,1.0000003333454632,1.0000004990740052,0.9999917560676863,0.9957312752106873,8.673617379884035,7806.255641895632]
You see the first couple of derivatives are good now, but then eventually it also becomes unstable – and this will happen with any FD method as you iterate it. But that's anyway not really a good approach: note that every evaluation of the n-th derivative requires 2 evaluations of the n−1-th. So, the complexity is exponential in the derivative degree.
A better approach to approximate the n-th derivative of an opaque function is to fit an n-th order polynomial to it and differentiate this symbolically/automatically. Or, if the function is not opaque, differentiate itself symbolically/automatically.
tl;dr: the dx denominator gets small exponentially quickly, which means that even small errors in the numerator get blown out of proportion.
Let's do some equational reasoning on the first "bad" approximation, the third derivative.
dif (dif (dif exp))
= { definition of dif }
dif (dif (\x -> (exp (x+dx) - exp x)/dx))
= { definition of dif }
dif (\y -> ((\x -> (exp (x+dx) - exp x)/dx) (y+dx)
- (\x -> (exp (x+dx) - exp x)/dx) y
)/dx)
= { questionable algebra }
dif (\y -> (exp (y + 2*dx) - 2*exp (y + dx) + exp y)/dx^2)
= { alpha }
dif (\x -> (exp (x + 2*dx) - 2*exp (x + dx) + exp x)/dx^2)
= { definition of dif and questionable algebra }
\x -> (exp (x + 3*dx) - 3*exp (x + 2*dx) + 3*exp (x + dx) - exp x)/dx^3
Hopefully by now you can see the pattern we're getting into: as we take more and more derivatives, the error in the numerator gets worse (because we are computing exp farther and farther away from the original point, x + 3*dx is three times as far away e.g.) while the sensitivity to error in the denominator gets higher (because we are computing dx^n for the nth derivative). By the third derivative, these two factors become untenable:
> exp (3*dx) - 3*exp (2*dx) + 3*exp (dx) - exp 0
-4.440892098500626e-16
> dx^3
9.999999999999999e-19
So you can see that, although the error in the numerator is only about 5e-16, the sensitivity to error in the denominator is so high that you start to see nonsensical answers.

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

List comprehension takes too much memory

I'm a beginner to Haskell and used it to solve some 50 problems of Project Euler but now I'm stuck at problem 66. The problem is that the compiled code (ghc -O2 --make problem66.hs) takes all my machine's free memory after 10-20 seconds. My code looks like this:
-- Project Euler, problem 66
diophantine x y d = x^2 - d*y^2 == 1
minimalsolution d = take 1 [(x, y, d) | y <- [2..],
let x = round $ sqrt $ fromIntegral (d*y^2+1),
diophantine x y d]
issquare x = (round $ sqrt $ fromIntegral x)^2 == x
main = do
print (map minimalsolution (filter (not . issquare) [1..1000]))
I have a hunch that the problem lies in the infinite list inside the list comprehension for minimalsolution.
I actually thought that due to lazyness, Haskell would evaluate the list only until it finds one element (because of take 1) and on the way discard everything for which diophantine evaluates to False. Am I wrong there?
Interestingly, I did not see this behaviour in ghci. Is it because processing inside ghci is so much slower that I just would have to wait until I see the memory consumption explode - or is it something else?
No spoilers, please. All I want to know is where the extreme memory consumption comes from and how I can fix it.
I haven't profiled before, so stone throwers are welcome.
Haskell determines that [2..] is a constant and is reused for every element of the list, despite take 1 using only one element of that list; so it memoizes the list for computing future elements of the same list. You get stuck computing value for d=61.
Edit:
What's interesting, this one terminates for [1..1000]:
minimalsolution d = take 1 [(x, y, d) | y <- [2..] :: [Int],
let x = round $ sqrt $ fromIntegral (d*y^2+1),
diophantine x y d]
Just added :: [Int]. Memory use looks stable at 1MB. Using Int64 reproduces the problem.
minimalsolution d = take 1 [(x, y, d) | y <- [2..] :: [Int64],
let x = round $ sqrt $ fromIntegral (d*y^2+1),
diophantine x y d]
Edit:
Well, as has been suggested, the difference is caused by overflow. The solution to d=61 is reported as (5983,20568,61), but 5983^2 is nowhere near 61*20568^2.
Inside of the comprehension creating unnecessary Double instances on each value of y.
I couldn't find a solution using list comprehensions that didn't have the space blowup. But rewriting using recursion yields a stable memory profile.
diophantine :: Int -> Int -> Int -> Bool
diophantine x y d = x^2 - d*y^2 == 1
minimalsolution :: Int -> (Int, Int, Int)
minimalsolution d = go 2
where
d0 = fromIntegral d
go a =
let y = fromIntegral a
x = round $ sqrt $ (d0*y^2+1) in
if diophantine x y d then
(x, y, d)
else
go (y+1)
For what it is worth I have tested this now after 6 years and this problem does not appear anymore. The memory consumption stays very low with GHC 8.6.5. I assume that this was indeed a problem in the compiler which has been fixed at some point.

Calling functions prefix vs. infix in Haskell

I've been wanting to learn Haskell, so recently I started working through the ProjectEuler problems. While writing the following factoring code I noticed that calling (/ n) returns a Float while (n `div`) returns an Int. I thought that infix notation was simply syntactic sugar in Haskell? Could someone explain what is going on? I would also appreciate any comments / suggestions / improvements, thank you.
import Data.List (sort)
factor :: Int -> [Int]
factor 0 = [1..]
factor n =
let f1 = [f | f <- [1..limit], n `mod` f == 0]
where limit = ceiling $ sqrt $ fromIntegral n
f2 = map (n `div`) f1 --vs. map (/ n) f1
in sort $ f1 ++ f2
div and / are two different functions:
/ is defined in class Fractional and it's meaning is an inverse operation to multiplication.
div is defined in class Integral and it's meaning is division of integers with truncation toward negative infinity.
You're right, infix notation is just a syntactic sugar. The expression x / y is the same as (/) x y, as well as div x y is the same as x `div` y.
There's nothing special going on. The div function is part of the Integral class and is being more specifically inferred as Int, given your explicit type signature. The / operator is part of the Fractional class. These are two different functions, one is not syntactic sugar for another!

Learning Haskell, care to help out with coding style?

I started learning haskell yesterday and I got stuck on a problem. After a bit of trying different things I thought I'd finally come here and ask how to fix this. Also, feel free to criticize the way I have done things so far so I can know what direction to go. Thanks.
module Main where
main = putStrLn lastPrime
where
lastPrime :: String
lastPrime = show(last(take 10001 primes))
primes :: [Int]
primes = [x| x <- [1..],length [a| a <- [1..lessen(x)], mod x a /= 0] == x - 2]
lessen :: Int -> Int
lessen a = ceiling(sqrt(a))
To fix your type error, you want this:
lessen :: Int -> Int
lessen a = ceiling (sqrt (fromIntegral a))
a has type Int, but sqrt is expecting a floating point type, and the easiest way to convert an integral type to another numeric type is fromIntegral.
In addition to the type error in lessen you have a logic error in primes:
length [a| a <- [1..lessen(x)], mod x a /= 0] == x - 2
You're (rightly) only considering elements up to lessen x. This has the consequence that the list will almost never have exactly x - 2 elements. As a consequence you'll get into an infinite loop when trying to get more than two elements out of that list (because there is no 3rd element for which the condition is true, but haskell doesn't know that so it iterates to infinity trying to find it).
Also note that taking the length of a list is an O(n) operation and there's almost always a better way to achieve what you want.
As a style note, I would recommend defining a separate method isPrime. This will make your code look like this:
module Main where
main = putStrLn lastPrime
where
lastPrime :: String
lastPrime = show(last(take 10001 primes))
isPrime x = length [a| a <- [1..lessen(x)], mod x a /= 0] == x - 2]
primes :: [Int]
primes = [x| x <- [1..], isPrime x]
lessen :: Int -> Int
lessen a = ceiling(sqrt (fromIntegral a))
This IMHO makes the list comprehension much more readable. However it still contains the bug. To get rid of the bug, I'd suggest defining isPrime using a different approach. Going up to lessen x is fine (except you should start from 2 because 1 cleanly divides everything), but instead of building a new list with all the divisors, you should just check whether any of the numbers in the range divides x. For this we can use the higher order function any, so we get this:
isPrime x = not (any (\a -> mod x a == 0) [2 .. lessen x])

Resources