I am teaching myself Haskell, and playing with list comprehensions. I wrote this list comprehension:
[ c | a <- [1..3], b <- [1..4], let c = hyp a b, c == round c]
I hoped it would produce the list of values c where c is an integer (c == round c), which would be only 5, but it does not compile. Playing around some more, I've found I can't really embed any functions in a list comprehension, I'm sure there is a way, I just don't know how.
Here's the error code:
<interactive>:158:1: error:
• Ambiguous type variable ‘t0’ arising from a use of ‘it’
prevents the constraint ‘(Floating t0)’ from being solved.
Probable fix: use a type annotation to specify what ‘t0’ should be.
These potential instances exist:
instance Floating Double -- Defined in ‘GHC.Float’
instance Floating Float -- Defined in ‘GHC.Float’
• In the first argument of ‘print’, namely ‘it’
In a stmt of an interactive GHCi command: print it
Thanks!
First of all, include necessary definitions in a question like this.
hyp :: Floating a => a -> a -> a
hyp a b = sqrt $ a^2 + b^2
Now. You can “embed” functions all right in list comprehensions. Apparently you just chose some unfortunate ones! round has the following type:
GHCi, version 7.10.2: http://www.haskell.org/ghc/ :? for help
Prelude> :t round
round :: (Integral b, RealFrac a) => a -> b
So, for round c == c to make sense, you'd need to have a number type that's both an instance of Integral and of RealFrac. In other words, this type would contain fractions, yet all its elements would be integers†. Well, you can't have your cake and eat it too!
This problem would have been much more evident, like so often in Haskell, if you had actually written out some type signatures. While fooling around like that, it often helps to just select some simple example type. Perhaps the most reasonable thing would seem:
Prelude> [ c | a <- [1..3], b <- [1..4], let c = hyp a b, c == round c] :: [Integer]
<interactive>:6:41:
No instance for (Floating Integer) arising from a use of ‘hyp’
In the expression: hyp a b
In an equation for ‘c’: c = hyp a b
In the expression:
[c |
a <- [1 .. 3], b <- [1 .. 4], let c = hyp a b, c == round c] ::
[Integer]
Ok, so Integer doesn't work because you're trying to do real arithmetic, with those square roots in hyp. This is not possible with Integer, you need a Floating type like Double. Let's try that:
Prelude> [ c | a <- [1..3], b <- [1..4], let c = hyp a b, c == round c] :: [Double]
<interactive>:8:55:
No instance for (Integral Double) arising from a use of ‘round’
In the second argument of ‘(==)’, namely ‘round c’
In the expression: c == round c
In a stmt of a list comprehension: c == round c
Ok, this is because as I said, round always gives integral-type results. However, you can always convert such an integral type to a Double again:
Prelude> [ c | a <- [1..3], b <- [1..4], let c = hyp a b, c == fromIntegral (round c)] :: [Double]
[5.0]
Note that this is not really a good solution though: you don't really want the result to be floating point if you go already check that the elements are really integral! I'd recommend in this case not just evaluating hyp as such at all. Better use this comprehension:
Prelude> [ c | a <- [1..3], b <- [1..4], let c² = a^2 + b^2; c = round . sqrt $ fromIntegral c², c^2==c²] :: [Integer]
[5]
One big argument for this version is that it does the comparison in Integer, not in Double. Floating-point equality comparison is something you should best stay away from entirely if you can help it; in this case it's mostly harmless because the interesting thing is the integer subset, which can in fact be represented exactly (unlike decimal fractions like 0.1). Still you ca get wrong results this way: in particular, for sufficiently large floating-point numbers, c == fromInteger (round c) will always be true, because above a certain threshold all values are integral after all.
Prelude> [ c | a <- take 4 [1000000000000..], b <- take 5 [1000000000000..], let c = hyp a b, c == fromIntegral (round c)] :: [Float]
[1.4142135e12,1.4142135e12,1.4142135e12,1.4142135e12,1.4142135e12,1.4142135e12,1.4142135e12,1.4142135e12,1.4142135e12,1.4142135e12,1.4142135e12,1.4142135e12,1.4142135e12,1.4142135e12,1.4142135e12,1.4142135e12,1.4142135e12,1.4142135e12,1.4142135e12,1.4142135e12]
But none of these are actually correct integral hypothenuses, as you can see with the version that does the comparison in Integer:
Prelude> [ c | a <- take 4 [1000000000000..], b <- take 5 [1000000000000..], let c² = a^2 + b^2; c = round . sqrt $ fromIntegral c², c^2==c²] :: [Integer]
[]
Strictly speaking, this improved version is also not safe though – it doesn't give false positives, but may not find actual Pythagorean triples because the lossy floating-point steps can already destroy equality. To do it real properly, you need an all-integral
intSqrt :: Integral a => a -> Maybe a
This could probably done quite efficiently by taking the float sqrt as a starting value for a few rounds of pseudo Newton-Raphson in integer arithmetic.
†In principle, the round function could also have a more relaxed signature.
round' :: (Num b, RealFrac a) => a -> b
round' = fromInteger . round
With that version, your original code would work.
Related
I'm just learning haskell (on my own, for fun) and I've come up against a wall.
My Question:
How can I define a function
flrt = (floor . sqrt)
When I try it in a file and compile, GCHi complains with the following:
AKS.hs:11:9:
No instance for (RealFrac Integer)
arising from a use of `floor'
Possible fix: add an instance declaration for (RealFrac Integer)
In the first argument of `(.)', namely `floor'
In the expression: (floor . sqrt)
In an equation for `flrt': flrt = (floor . sqrt)
AKS.hs:11:17:
No instance for (Floating Integer)
arising from a use of `sqrt'
Possible fix: add an instance declaration for (Floating Integer)
In the second argument of `(.)', namely `sqrt'
In the expression: (floor . sqrt)
In an equation for `flrt': flrt = (floor . sqrt)
I don't understand why the resulting function isn't just Int -> Int.
I've just finished my second year of CS and done a basic PL course. I've heard of, but don't quite get types yet. I tried reading through a few haskell tutorials but it's all going above my head.
P.S. - I also don't understand what a monad is. (a lot of the other questions that my search turned up talked about these)
P.P.S. - My full source
bar = \a b -> if (2^a) > b
then (a-1)
else bar (a+1) b
foo = bar 1
flrt :: Integer -> Integer
flrt = (floor . sqrt)
aks target = if (target < 2)
then putStr "Not a Prime.\n\n"
else if elem (mod target 10) [0,2,4,5,6,8]
then putStr "Composite\n\n"
else if (elem target) [a^b | a <- [3,5..(flrt target)], b <- [1.. (foo target)]]
then putStr "Composite\n\n"--}
else
putStr "filler"
The problem is that you're trying to use Integer as the input. Haskell is strongly typed, which means there are no implicit coercions or conversions of any kind. Look at signatures of functions you're trying to compose:
sqrt :: Floating a => a -> a
floor :: (RealFrac a, Integral b) => a -> b
And at the signature of your function inferred by GHC:
> :t floor . sqrt
floor . sqrt :: (RealFrac b, Integral c, Floating b) => b -> c
So, to have a function that goes from Integer (which doesn't have a Floating instance) to Integer, you have to first convert your argument to Floating, which can be done by using fromIntegral:
> :t floor . sqrt . fromIntegral
floor . sqrt . fromIntegral :: (Integral a, Integral c) => a -> c
As copumpkin remarked, it might actually be a bad idea to convert to floating point here, because this comes with loss of precision and therefore might, even with rounding, yield incorrect results for sufficiently large integer inputs.
I assume all numbers you're dealing with will at least be small enough that there is some floating-point representation for them, e.g. all are < 10300. But, for instance
Prelude> round(sqrt.fromInteger$10^60 :: Double) ^ 2
1000000000000000039769249677312000395398304974095154031886336
Prelude> {- and not -} 10^60 {- == (10^30)^2 == (sqrt$10^60) ^ 2 -}
1000000000000000000000000000000000000000000000000000000000000
Which is way off, in terms of absolute difference. Still it's certainly a rather good approximation relative to the numbers themselves, so you can use it as a quickly determined starting point for an algorithm to find the exact result. You can implement Newton/Raphson (in this case AKA Heron) with Integers:
flrt :: Integer -> Integer -- flrt x ≈ √x, with flrt x^2 ≤ x < flrt(x+1)^2
flrt x = approx (round . (sqrt::Double->Double) . fromInteger $ x)
where approx r
| ctrl <= x, (r+1)^2 > x = r
| otherwise = approx $ r - diff
where ctrl = r^2
diff = (ctrl - x) // (2*r) -- ∂/∂x x² = 2x
a//b = a`div`b + if (a>0)==(b>0) then 1 else 0 -- always away from 0
This now works as desired:
*IntegerSqrt> (flrt $ 10^60) ^ 2
1000000000000000000000000000000000000000000000000000000000000
The division always away from 0 in the Newton-Raphson correction is here necessary to prevent getting stuck in an infinite recursion.
I need to write a function or functions in Haskell that can solve the Chinese Remainder Theorem. It needs to be created with the following definition:
crt :: [(Integer, Integer)] -> (Integer, Integer)
That the answer looks like
>crt [(2,7), (0,3), (1,5)]
(51, 105)
I think I have the overall idea, I just don't have the knowledge to write it. I know that the crt function must be recursive. I have created a helper function to split the list of tuples into a tuple of two lists:
crtSplit xs = (map fst xs, product(map snd xs))
Which, in this example, gives me:
([2,0,1],105)
I think what I need to do know is create a list for each of the elements in the first list. How would I begin to do this?
Chinese remainder theorem has an algebraic solution, based on the fact that x = r1 % m1 and x = r2 % m2 can be reduced to one modular equation if m1 and m2 are coprime.
To do so you need to know what modular inverse is and how it can efficiently be calculated using extended Euclidean algorithm.
If you put these pieces together, you can solve Chinese remainder theorem with a right fold:
crt :: (Integral a, Foldable t) => t (a, a) -> (a, a)
crt = foldr go (0, 1)
where
go (r1, m1) (r2, m2) = (r `mod` m, m)
where
r = r2 + m2 * (r1 - r2) * (m2 `inv` m1)
m = m2 * m1
-- Modular Inverse
a `inv` m = let (_, i, _) = gcd a m in i `mod` m
-- Extended Euclidean Algorithm
gcd 0 b = (b, 0, 1)
gcd a b = (g, t - (b `div` a) * s, s)
where (g, s, t) = gcd (b `mod` a) a
then:
\> crt [(2,7), (0,3), (1,5)]
(51,105)
\> crt [(2,3), (3,4), (1,5)] -- wiki example
(11,60)
Without going into algebra, you can also solve this with brute force. Perhaps that's what you've been asked to do.
For your example, create a list for each mod independent of the other two (upper bound will be least common multiple of the mod, assuming they are co-prime as a precondition, product, i.e. 105). These three list should have one common element which will satisfy all constraints.
m3 = [3,6,9,12,15,...,105]
m5 = [6,11,16,21,...,101]
m7 = [9,16,23,30,...,100]
you can use Data.Set to find the intersection of these lists. Now, extend this logic to n number of terms using recursion or fold.
Update
Perhaps an easier approach is defining a filter to create a sequence with a fixed remainder for a modulus and repeatedly apply for the given pairs
Prelude> let rm (r,m) = filter (\x -> x `mod` m == r)
verify that it works,
Prelude> take 10 $ rm (1,5) [1..]
[1,6,11,16,21,26,31,36,41,46]
now, for the given example use it repeatedly,
Prelude> take 3 $ rm (1,5) $ rm (0,3) $ rm (2,7) [1..]
[51,156,261]
of course we just need the first element, change to head instead
Prelude> head $ rm (1,5) $ rm (0,3) $ rm (2,7) [1..]
51
which we can generalize with fold
Prelude> head $ foldr rm [1..] [(1,5),(0,3),(2,7)]
51
I'm trying to write a program in Haskell
that gets a list (of integer) and prints out the number of elements that are bigger than the list's average
So far I tried
getAVG::[Integer]->Double
getAVG x = (fromIntegral (sum x)) / (fromIntegral (length x))
smallerThanAVG:: [Integer]->Integer
smallerThanAVG x = (map (\y -> (if (getAVG x > y) then 1 else 0)) x)
For some reason I'm getting this error
Couldn't match expected type `Double'
against inferred type `Integer'
Expected type: [Double]
Inferred type: [Integer]
In the second argument of `map', namely `x'
It could be that I haven't written the logic correctly, although I think I did..
Ideas?
These errors are the best kind, because they pinpoint where you have made a type error.
So let's do some manual type inference. Let's consider the expression:
map (\y -> (if (getAvg x > y) then 1 else 0)) x
There are a few constraints we know off the bat:
map :: (a -> b) -> [a] -> [b] -- from definition
(>) :: Num a => a -> a -> Bool -- from definition
getAvg :: [Integer] -> Double -- from type declaration
1, 0 :: Num a => a -- that's how Haskell works
x :: [Integer] -- from type declaration of smallerThanAVG
Now let's look at the larger expressions.
expr1 = getAvg x
expr2 = (expr1 > y)
expr3 = (if expr2 then 1 else 0)
expr4 = (\y -> expr3)
expr5 = map expr4 x
Now let's work backwards. expr5 is the same as the RHS of smallerThanAVG, so that means it has the same result type as what you've declared.
expr5 :: Integer -- wrong
However, this doesn't match our other constraint: the result of map must be [b] for some b. Integer is definitely not a list (although if you get facetious, it could be coerced into a list of bits). You probably meant to sum that list up.
expr6 = sum expr5
sum :: Num a => [a] -> a
Now let's work forwards.
expr1 :: Double -- result type of getAvg
y :: Double -- (>) in expr2 requires both inputs to have the same type
expr4 :: (Integer -> [a]) -- because for `map foo xs` (expr5)
-- where xs :: [a], foo must accept input a
y :: Integer -- y must have the input type of expr4
Herein lies the conflict: y cannot be both a Double and an Integer. I could equivalently restate this as: x cannot be both a [Double] and [Integer], which is what the compiler is saying. So tl;dr, the kicker is that (>) doesn't compare different types of Nums. The meme for this sort of problem is: "needs more fromIntegral".
(getAvg x > fromIntegral y)
Your code has two errors.
Although the type signature in the code declares that smallerThanAVG x evaluates to an Integer, its code is map ... x, which clearly evaluates to a list instead of a single Integer.
In the code getAVG x > y, you are comparing a Double to an Integer. In Haskell, you can only compare two values of the same type. Therefore, you have to use fromIntegral (or fromInteger) to convert an Integer to a Double. (This is essentially what caused the error message in the question, but you have to get used to it to figure it out.)
There are several ways to fix item 1 above, and I will not write them (because doing so would take away all the fun). However, if I am not mistaken, the code you are aiming at seems like counting the number of elements that are smaller than the average, in spite of what you write before the code.
Styling tips:
You have many superfluous parentheses in your code. For example, you do not have to parenthesize the condition in an if expression in Haskell (unlike if statement in C or Java). If you want to enjoy Haskell, you should learn Haskell in a good style instead of the Haskell which just works.
You call the variable which represents a list “x” in your code. It is conventional to use a variable name such as xs to represent a list.
Others have explained the errors beautifully.
I'm still learning Haskell but I'd like to provide an alternative version of this function:
greaterThanAvg :: [Int] -> [Int]
greaterThanAvg xs = filter (>avg) xs
where avg = sum xs `div` length xs
cnt = length $ greaterThanAvg [1,2,3,4,5]
This is not a duplicate question. Read below...
I'm declaring the following function:
divisors x = [(a, x/a) | a <- [2..(sqrt x)], x `mod` a == 0]
What I want to obtain is the divisors of x: A list of tuples that will contain (n, k) such as n * k = x
Example:
> divisors x
[(1,10), (2, 5)]
Why the above code isn't working?
It gives me the error:
*Main> divisors 10
<interactive>:1:0:
Ambiguous type variable `t' in the constraints:
`Floating t'
arising from a use of `divisors' at <interactive>:1:0-10
`Integral t'
arising from a use of `divisors' at <interactive>:1:0-10
Probable fix: add a type signature that fixes these type variable(s)
I've tried manually setting the signature of the function without success...
The problem is sqrt returns a Floating a, and you really just want integers when finding divisors. You can turn a Floating a into an Integral a with ceiling, floor or round. I will use ceiling, as I'm not sure if using floor or average won't skip a divisor.
The sqrt function also only accepts a floating number, so you will have to convert an integer into a floating before giving it to it (this can be done with fromIntegral).
Also, you use /, which also works with floating numbers. Using div is better as it works with integral numbers (rounding when necessary).
divisors x = [(a, x `div` a) | a <- [2..(ceiling $ sqrt $ fromIntegral x)], x `mod` a == 0]
With this, divisors 10 will give [(2,5)] (your code stops the (1,10) case from happening - I'm guessing this was intentional). Unfortunately you will get duplicates, eg divisors 12 will return [(2,6),(3,4),(4,3)], but that shouldn't be too hard to fix if it is a problem.
You can see the problem if you ask for the type:
divisors :: (Integral t, Floating t) => t -> [(t, t)]
and then check what things are both Integral and Floating:
Prelude> :info Floating
class Fractional a => Floating a where
instance Floating Float -- Defined in GHC.Float
instance Floating Double -- Defined in GHC.Float
and
Prelude> :info Integral
class (Real a, Enum a) => Integral a where
instance Integral Integer -- Defined in GHC.Real
instance Integral Int -- Defined in GHC.Real
so, it can be neither Int, Integer, Float or Double. You're in trouble...
Thankfully, we can convert between types, so that while sqrt needs a Floating, and mod needs an Integral (btw, rem is faster), we can either, e.g., do away with floating point division:
divisors :: Integer -> [(Integer, Integer)]
divisors x = [(a, x `div` a) | a <- [2..ceiling (sqrt (fromIntegral x))], x `rem` a == 0]
> divisors 100
[(2,0),(4,0),(5,0),(10,0)]
However, you need to think hard about what you really mean to do when converting integer types to floating point, via sqrt...
In Haskell, integer division and fractional division are different operations, and have different names. The slash operator, /, is for fractional division. Integer division is accomplished with div or quot (the difference between the two having to do with the behavior when there are negative numbers involved).
Try replacing x/a with
x `quot` a
instead.
The compiler error tells you exactly this: that you're treating a type sometimes as an integral number (by using mod), and sometimes as a fractional number (by using /), and it's not sure how to pick a type that acts like both of those.
You'll have a similar issue with sqrt, once that's sorted, though. There again, you need to be consistent about whether your types are integers or (in that case) floating point. For the purpose of finding possible divisors, it should suffice to range up to the greatest integer less that the floating point, so consider using floor (sqrt (fromIntegral x))). The fromIntegral converts x (which must have an integral type) to a different type -- in this case, it will default to Double. The floor then converts the Double result back into an integral type.
Instead of taking the square-root to bound the search, you can allow the comprehension to range over an infinite list, and use takeWhile to stop the search when the remainder is greater than the divisor:
divisors x = takeWhile (uncurry (<=)) [(a, x `div` a) | a <- [1..], x `mod` a == 0]
> divisors 100
[(1,100),(2,50),(4,25),(5,20),(10,10)]
Note: your original example shows (1,10) as one of the divisors of 10, so I started the comprehension from 1 instead of 2.
Hmm, this does search beyond the square-root until it hits the next factor above.
How about this:
divisors x = [(a, x `div` a) | a <- takeWhile ((<= x) . (^2)) [1..], x `mod` a == 0]
I'm still new and trying to create a list for use in a function and want to keep it as small as possible which happens to be logBase x y.
but I'm having trouble getting logBase into something I can use in this list.
[1 .. (logBase x y)]
Any suggestions?
You don't post what type error you get, but I imagine it is something like this:
Prelude> let x = 2
Prelude> let y = 7
Prelude> [1 .. (logBase x y)]
<interactive>:1:7:
No instance for (Floating Integer)
arising from a use of `logBase' at <interactive>:1:7-17
Possible fix: add an instance declaration for (Floating Integer)
In the expression: (logBase x y)
In the expression: [1 .. (logBase x y)]
In the definition of `it': it = [1 .. (logBase x y)]
The problem is that:
Prelude> :t logBase
logBase :: (Floating a) => a -> a -> a
returns a type in the Floating class, while other variables in your program (1, 'x', 'y') are of integral type.
I presume you want a sequence of Integers?
Prelude> :set -XNoMonomorphismRestriction
Prelude> let x = 2
Prelude> let y = 42
Prelude> [1 .. truncate (logBase x y)]
[1,2,3,4,5]
Use truncate, celing or floor.
You probably want one of the functions list here. Hoogle and Hayoo! are great tools for this kind of thing since they let you put in the type of the function you want and get back a list of functions. With Haskell's rich type system this can be a very helpful tool, much more so than dynamically typed languages or even statically typed languages like C or Java.
You probably want some sort of rounding, truncate, floor, or ceiling function. Ints and Floats are different types (as you've seen) and the compiler won't let you mix them. I'll find a reference in a minute.