Apply comparison between Integral and Fractional - haskell

I want to check if an Integral is a square:
isSquare :: Integral n => n -> Bool
isSquare n = (>1) $ length (filter (\x -> n / x == x) numList)
where numList = reverse [1..n]
Apart from whether or not iterating through a list is the right approach here, when I try to compile this function I get the error:
No instance for (Fractional Int) arising from a use of ‘/’
My understanding of this is that since I am binding n to the Integral type, by dividing it I am breaking the function's rigid type construction. How can I fix my function so that it compiles?

You could add fromIntegral to everything to get Fractionals:
filter (\x -> fromIntegral n / fromIntegral x == fromIntegral x) numList
Or just square the number instead:
filter (\x -> n == x ^ 2)
Also, your length check shouldn’t be >1. ==1 would make more sense, but you should use null to avoid having to try every number every time (besides using a faster algorithm in the first place).
isSquare :: Integral a => a -> Bool
isSquare n = not $ null $ filter (\x -> n == x ^ 2) numList
where numList = [n,n-1..1]

Related

Struggling with Haskell type system

I am trying to learn some Haskell by doing basic tasks in the particular case I am trying to implement some basic function for primality check, but I really can figure out the types, my code is
isPrime :: (Num a) => a -> Bool
isPrime n
| n <= 1 = False
| otherwise = not $ 0 `elem` map (mod n) [2..m] where m = floor $ sqrt n
I tried instead of (Num a) => a to use different number types or to use sqrt with fromIntegral but I still get error messages, like:
*Could not deduce (Floating a) arising from a use of `sqrt'
from the context: Num a
bound by the type signature for:
isPrime :: forall a. Num a => a -> Bool
at Helpers.hs:5:1-31
Possible fix:
add (Floating a) to the context of
the type signature for:
isPrime :: forall a. Num a => a -> Bool
* In the second argument of `($)', namely `sqrt n'
In the expression: floor $ sqrt n
In an equation for `m': m = floor $ sqrt n
| otherwise = not $ 0 `elem` map (mod n) [2..m] where m = floor $ sqrt n
I can really use some help here, thank you in advance.
As others have mentioned, the use of mod requires a to be Integral, and the use of sqrt requires a to be Floating. Judging by the name of your function, I'm assuming that you want to use it on integral types.
So, you can fix this by changing your signature to isPrime :: (Integral a) => a -> Bool, then precomposing sqrt with fromIntegral. You could do something like
where m = floor . sqrt . fromIntegral $ n
Another option would be to replace [1..m] with something like takeWhile (\x -> x * x <= n) [1..] to avoid the need for Floating.
You have two problems in your code:
Incompatible types.
Calling both sqrt n and (mod n) reqiure n to be both Floating and Integral at the same time.
Insufficient context. Requiring only (Num a) does not allow neither of the operations.
A possible fix would be: a) narrow down type context to a much more concise (Integral a); b) add fromIntegral to sqrt's argument:
isPrime :: Integral a => a -> Bool
isPrime n
| n <= 1 = False
| otherwise = not $ 0 `elem` map (mod n) [2..m] where m = floor $ sqrt $fromIntegral n
The issue the compiler is describing is that you're applying incompatible operations to the same type: mod requires Integral a, sqrt requires Floating a, and no type satisfies both. You could work around that using type conversions like fromIntegral and ceiling, but you'd want to be careful to avoid rounding errors. For my test, I removed the type constraint and used m = ceiling $ sqrt $ fromIntegral n, which led to the inferred type isPrimeSqrt :: Integral a => a -> Bool.
Another approach is to consider why the conflict was hit and look for other solutions. The reason for sqrt is to produce an optimized stopping point for the test. Can we find that stopping point in another manner?
As it turns out, while division is expensive, it frequently produces two results: the quotient and remainder. With mod you're looking for the latter, but we have divMod and quotRem which produce both. So it could be worth testing if that's notably slower than the plain mod test (benchmark results, comparing [2..] vs [2..m]).
isPrime n = (n > 1) && null (filter isFactor (takeWhile notTooHigh divisors))
where notTooHigh (divisor,quotient,_) = divisor <= quotient
isFactor (_,_,remainder) = remainder == 0
divisors = [(divisor,quotient,remainder) |
divisor <- 2:[3,5..],
let (quotient,remainder) = quotRem n divisor]

Haskell - From generic to Integer | No instance for (RealFrac Integer) arising from a use of ‘floor’

I'm learning haskell.
I'm trying to solve a problem in which you're given a number (n) and you have to find a pair (m, k) where m^k would make n a perfect power.
n is a perfect power if there exist natural numbers m > 1, and k > 1
such that m^k = n.
This is what I came up with so far
module Test where
isPerfectPowerOf :: (Floating p, Enum p, RealFrac p) => p -> Maybe [(p, p)]
isPerfectPowerOf i
| null perfectList = Nothing
| otherwise = Just perfectList
where perfectList = filter (\(x, _) -> floor x == x) [(logBase x i, x) | x <- [2 .. (i - 1)]]
and it works.
But as you can see, with very generic types. What I want is for it to work with
isPerfectPowerOf :: Integer -> Maybe [(Integer, Integer)]
So for debugging purposes I placed this signature over the code which gave me these errors
severity: 'Error'
message: ' • No instance for (RealFrac Integer) arising from a use of ‘floor’
• In the first argument of ‘(==)’, namely ‘floor x’
In the expression: floor x == x
In the first argument of ‘filter’, namely
‘(\ (x, _) -> floor x == x)’
severity: 'Error'
message: ' • No instance for (Floating Integer)
arising from a use of ‘logBase’
• In the expression: logBase x i
In the expression: (logBase x i, x)
In the second argument of ‘filter’, namely
‘[(logBase x i, x) | x <- [2 .. (i - 1)]]’
So if I'm not completely off the mark I'll need to somehow typecast floor's and logBase's inputs properly.
floor :: (RealFrac a, Integral b) => a -> b
logBase :: Floating a => a -> a -> a
How should I go about doing it?
Or if it isn't the problem what could be?
So you tried:
perfectList :: Integer -> [(Integer, Integer)]
perfectList i = filter (\(x, _) -> floor x == x) [(logBase x i, x) | x <- [2 .. (i - 1)]]
(I'm going to deal with perfectList here for the sake of brevity. Note, though, that the conversion to Maybe in isPerfectPowerOf is perhaps redundant, as the nothingness of the Maybe result is equivalent to the emptiness of the list.)
That results in the two type errors you quoted. The first one arises because the argument to floor must be of some RealFrac type, and Integral isn't one of them. Similarly, the second error arises because logBase takes and returns values of some Floating type (and so you need to not only convert the arguments to floating-point but also convert the result back to Integer). Performing these adjustments results in:
perfectList :: Integer -> [(Integer, Integer)]
perfectList i = fmap (\(k, x) -> (floor k, x))
. filter (\(k, _) -> fromIntegral (floor k) == k)
$ [(logBase (fromIntegral x) (fromIntegral i), x) | x <- [2 .. (i - 1)]]
(Note that I have renamed your log variable, for the sake of clarity; you might also want to swap the order of the elements in the pairs.)
Since you are using a list comprehension already, it is easier to shift the fmap and the filter into it:
perfectList :: Integer -> [(Integer, Integer)]
perfectList i = [(k', x) | x <- [2 .. (i - 1)]
, let k = logBase (fromIntegral x) (fromIntegral i), let k' = floor k
, fromIntegral k' == k
]
On a final note, using floor to check whether a floating-point number is "really" a round number isn't fully reliable:
GHCi> fromIntegral (floor (logBase 2 (2**29))) == logBase 2 (2**29)
False
That being so, an ultimately sounder approach would be switching to an algorithm that finds perfect powers using integer arithmetic throughout, thus avoiding floating-point altogether. (While I suspect you'd want to implement that yourself, for an off-the-shelf solution check the Math.NumberTheory.Powers module from the arithmoi package.)

Ambiguous type variable in combination of sqrt and floor

Trying to implement a function for listing all prime numbers in some range of numbers, I know when I am checking for factors I do not have to check beyond the sqrt of that that number.
factors n = [x | x <- [1..(floor (sqrt n))], mod n x == 0]
prime n = factors n == [1,n]
listPrimesFromTill n z = [ xs | xs <- [n..z], prime xs == True]
I've been browsing for answers and I tried various methods like type checking using
factors :: (RealFrac b, Integral c, Floating b) => b -> c
but have had no luck.
Any help is appreciated!
It seems like you looked at the code you wrote and figured the types out after. In general, Haskell development is the other way around: First you figure out the types, then you implement the functions. What type should factors have? Well, you can only factorize integers, so something of type, so this seems sensible:
factor :: Integral a => a -> [a]
Now when trying to compile your code we get the following error:
Could not deduce (Floating a) arising from a use of `sqrt` from the context (Integral a)
and
Could not deduce (RealFrac a) arising from a use of `sqrt` from the context (Integral a)
It complains that you specified Integral a but it needs Floating a for sqrt. We can do this by usinf fromIntegral:
sqrt :: Floating a => a -> a
fromIntegral :: (Integral a, Num b) => a -> b
factors :: Integral a => a -> [a] vvvvvvvvvvvvvv
factors n = [x | x <- [1..(floor (sqrt (fromIntegral n)))], mod n x == 0]
To preserve readability,
factors n = [x | x <- [1..isqrt n], mod n x == 0]
where isqrt = floor . sqrt . fromIntegral

GHC not deducing the way I would like it to :-(

chainQuery :: (Enum a, Integral a, Ord b) => a -> b -> [c]
chainQuery n min = map length $ filter beatingLength $ map chain [1..n]
where
beatingLength :: [a] -> Bool
beatingLength xs = length xs > min
chain :: (Integral a) => a -> [a]
chain n
| n <= 1 = [n]
| even n = n:(chain $ div n 2)
| otherwise = n:(chain $ n * 3 + 1)
In the code sample above why isn't GHC able to deduce that 'c' is an Int by looking at the type definition for length?
Why does GHC need to know anything about 'b' other than that it is an Ord?
Is there a better way to write this function?
GHC is able to infer [Int] as the result type for the function. The problem is that you've claimed in your type signature that it should be more polymorphic, that the result could be a list of any type, which does not make sense since the return value comes from the map length so it must have type [Int]. This is what GHC is complaining about when it says Could not deduce (c ~ Int).
You're comparing min to length xs. The greater-than operator has the type (>) :: (Ord a) => a -> a -> Bool, which means that both sides must be the same type. The type of length xs is Int, so this forces min to be Int as well.
Probably. For example, you can map the length before doing the filtering. This makes it easy to use an operator section instead of your beatingLength function. You can also move the parenthesis to save a use of $ to make the code a bit neater.
chainQuery n min = filter (> min) $ map (length . chain) [1..n]
where chain n | n <= 1 = [1]
| even n = n : chain (n `div` 2)
| otherwise = n : chain (3*n + 1)
For reference, the easiest way to solve a problem like this is to remove your type signature and see what type was inferred in GHCi using the :t command. In this case, the inferred type is
*Main> :t chainQuery
chainQuery :: Integral a => a -> Int -> [Int]

Haskell's if statement for error checking

I wrote a function for the Haar wavelet transformation given that the input is a List with a power of 2. I was trying to error check by making sure that the length of the List is a power of 2 before preforming the transformation. I am comparing the log base 2 of the length of the list to see if it comes out evenly (nothing to the right of the decimal point). I think there is something going on with the if statement in haskell that I am not used to in other languages. It works perfectly if I don't error check and just call haar with the proper argument.
haar :: (Fractional a) => [a] -> [a]
haar xs = if logBase 2 (fromIntegral (length xs)) /= truncate (logBase 2 (fromIntegral (length xs)))
then error "The List must be a power of 2"
else haarHelper xs (logBase 2 (fromIntegral (length xs)))
haarHelper xs 1 = haarAvgs xs ++ haarDiffs xs
haarHelper xs level = haarHelper (haarAvgs xs ++ haarDiffs xs) (level - 1)
haarAvgs [] = []
haarAvgs (x:y:xs) = ((x + y) / 2.0) : haarAvgs xs
haarDiffs [] = []
haarDiffs (x:y:xs) = ((x - y) / 2.0) : haarDiffs xs
I am getting the following error message:
functions.hs:52:13:
Ambiguous type variable `t' in the constraints:
`Floating t'
arising from a use of `logBase' at functions.hs:52:13-48
`Integral t'
arising from a use of `truncate' at functions.hs:52:53-99
Probable fix: add a type signature that fixes these type variable(s)
Failed, modules loaded: none.
There's a much simpler and faster implementation to check that a positive integer is a power of two:
import Data.Bits
powerOfTwo' n = n .&. (n-1) == 0
(Note: this omits the check that n is positive, assuming we can rely on it coming from length.)
Explanation, for the curious:
This algorithm relies on the unique property that only powers of 2 have a single 1 bit (by definition), and decrementing them inverts all the lower bits:
2^n = 100000...
2^n - 1 = 011111...
This leaves no bits in common, making their bitwise-and zero.
For all non-powers-of-two, the decrement will leave at least the highest 1 bit unchanged, keeping the bitwise-and result non-zero.
(Wikipedia: Fast algorithm to check if a positive number is a power of two)
haar :: (Fractional a) => [a] -> [a]
haar xs | r /= (truncate r) = error "The List must be a power of 2"
| otherwise = haarHelper xs (logBase 2 (fromIntegral (length xs)))
where r = logBase 2 (fromIntegral (length xs))
Yea, seems like its something with truncate. Easier way to write if then statements with haskell is shown above. Might help with the debugging a bit.
I think i may know. I think truncate is returning an int where the other number is a float.
Try this
haar :: (Fractional a) => [a] -> [a]
haar xs | r /= w = error "The List must be a power of 2"
| otherwise = haarHelper xs (logBase 2 (fromIntegral (length xs)))
where
r = logBase 2 (fromIntegral (length xs))
w = intToFloat (truncate r)
haarHelper xs 1 = haarAvgs xs ++ haarDiffs xs
haarHelper xs level = haarHelper (haarAvgs xs ++ haarDiffs xs) (level - 1)
haarAvgs [] = []
haarAvgs (x:y:xs) = ((x + y) / 2.0) : haarAvgs xs
haarDiffs [] = []
haarDiffs (x:y:xs) = ((x - y) / 2.0) : haarDiffs xs
intToFloat :: Int -> Float
intToFloat n = fromInteger (toInteger n)
To complement Matt's answer:
haar :: (Fractional a) => [a] -> [a]
haar xs | r /= (fromIntegral $ truncate r) = error "The List must be a power of 2"
| otherwise = haarHelper xs r
where r = logBase 2 (fromIntegral (length xs))
Convert the Integral result of truncate using fromIntegral
You can use the definition of r in haarHelper xs r
Here's a version of haar that I'll argue is a little nicer:
haar :: (Fractional a) => [a] -> [a]
haar xs = maybe (error "The List must be a power of 2")
(haarHelper xs)
(intLogBase 2 $ length xs)
intLogBase :: (Integral a) => a -> a -> Maybe Int
intLogBase b n = intLogBase' b 1 n
where
intLogBase' b p 1 = Just p
intLogBase' b p n
| r /= 0 = Nothing
| otherwise = intLogBase' b (p + 1) q
where (q, r) = quotRem n b
intBaseLog is a variation of baseLog that works for integers and returns Nothing if the given number isn't a power of the given base. Otherwise it returns the power wrapped in a Just. Unlike with logBase and truncate there's no conversion to floating point numbers: we've got integers all the way through.
The maybe function in Haar takes three arguments. It will evaluate its last argument, and if it's a Nothing it will return the first argument (in this case the error). If the last argument evaluates to a Just, it applies the second argument to the thing inside the Just and returns that.
The problem here is unrelated to the if expression. As mentioned in other answers, it is in your condition where you compare "logBase (...)" to "truncate (logBase (...))". One returns a Floating type, the other returns an Integral type. There are no types (in the standard libraries) that implement both classes, so that condition can't be well-typed as-is.
A pattern I use occasionally when working with powers of two is to keep a list of powers of two and just check whether the number is in that list. For example:
powersOfTwo :: [Integer]
powersOfTwo = iterate (*2) 1
isPowerOfTwo x = xInt == head (dropWhile (<xInt) powersOfTwo)
where xInt = toInteger x
I haven't tested, but my gut tells me that for most purposes this is probably faster than "logBase 2". Even if not, it's more appropriate because it doesn't involve any floating-point math. In particular, your current approach isn't going to work even with the types fixed: truncate (logBase 2 512) == truncate (logBase 2 550) (Edit: although I think I probably misunderstood your intent when I wrote this at first, i realize now that you probably meant to check whether logBase 2 (...) is an exact integer value by comparing the truncated version to a non-truncated version, not by comparing to any known value).

Resources