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]
Related
I need to check if a list only contains odd numbers, bigger than 10.
This is what I did.
f :: [Int] -> Bool
f xs= [x |x<-xs, x >10, odd x]
Why does this not work?
When you write [x |x<-xs, x >10, odd x] you're making up a list of Ints, a [Int], not a Boolean. For instance you can verify that
[x | x <- [1..20], x > 10, odd x] is the list [11,13,15,17,19]. So it does contain the numbers that you want, but how do you tell that those are all of the numebrers in xs?
You could certainly equate that list to xs itself, and that would work:
f xs = xs == [x |x<-xs, x >10, odd x]
This way the == ensures that when you only take odd numbers greater than 10 from xs you get back exactly xs, meaning that all numbers satisfy the predicate.
Maybe this is the mistake you were looking for.
I'm not sure whether this solution traverses xs twice (once to extract the entries satisfying the predicate, and once to check for equality) or not. It looks very simple, so I can't help but think that the list is traversed only once.
Anyway, another strategy is to stick to your request: you want all numbers x from the list xs for which odd x and x > 10 are both True:
f :: [Int] -> Bool
f xs = all (\x -> odd x && x > 10) xs
By noticing that both sides have a trailing xs, you can reduce the definition:
f :: [Int] -> Bool
f = all (\x -> odd x && x > 10)
And that lambda, if you want, could be define more succintly as (odd & (> 10)), thus getting
f :: [Int] -> Bool
f = all (odd & (> 10))
provided you import Control.Monad (liftM2) and define
(&) :: (a -> Bool) -> (a -> Bool) -> (a -> Bool)
(&) = liftM2 (&&)
Your type signature mentions that the function returns a boolean value, but your proposed body returns a list of numbers. Haskell has no automatic conversions such as Lisp.
Should you wish to stick to pedestrian code, you could get the sublist of offending numbers, and just check that the sublist is empty.
f :: [Int] -> Bool
f xs = let offenders = [x | x <- xs, x <= 10 || even x]
in (null offenders)
Note that due to the laziness of the language runtime, evaluation of offenders stops as soon as we find a first element.
Should you want something a bit more haskell-ish, you can use the sequence :: (Traversable t, Monad m) => t (m a) -> m (t a) polymorphic library function to turn a list of predicates into a single function returning a list of boolean values, then pass that list to and. That checks one number.
Then use all to apply these checks to all numbers in the input list. Like this:
f2 :: [Int] -> Bool
f2 = all (and . sequence [(>10), odd])
Explanation:
To understand how exactly the sequence function gets specialized by the compiler, one can use the TypeApplications language extension.
With the extension enabled, given 3 type arguments, expression sequence #tt #tm #ta maps tt to the Traversable instance, tm to the Monad instance and ta to argument type a.
$ ghci
GHCi, version 8.8.4: https://www.haskell.org/ghc/ :? for help
λ>
λ> :type sequence
sequence :: (Traversable t, Monad m) => t (m a) -> m (t a)
λ>
λ> :set -XTypeApplications
λ>
We start with the easiest part, mapping tt to lists and ta to Bool, leaving tm undefined as an underscore _:
λ>
λ> :type sequence #[] #_ #Bool
sequence #[] #_ #Bool :: Monad _ => [_ Bool] -> _ [Bool]
λ>
Now, if we assign tm to “function of an Int variable”, we have the whole picture:
λ>
λ> :type sequence #[] #((->)Int) #Bool
sequence #[] #((->)Int) #Bool :: [Int -> Bool] -> Int -> [Bool]
λ>
The last type can be interpreted as [Int -> Bool] -> (Int -> [Bool]), that is, function sequence transforming a list of predicates into a single function returning a list of boolean values.
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]
In book.realworldhaskell.org, types and functions part under Conditional evaluation section, it is given the following example:
-- file: ch02/myDrop.hs
myDrop n xs = if n <= 0 || null xs
then xs
else myDrop (n - 1) (tail xs)
I did understand the implementation of the function, but my question is that how does Haskell know xs is a list ?
Type inference
You write:
myDrop n xs = if n <= 0 || null xs
then xs
else myDrop (n - 1) (tail xs)
So Haskell first assumes that the function has type myDrop :: a -> (b -> c) (it first does not make any assumptions regarding the types). So in memory we store:
myDrop :: a -> b -> c
n :: a
xs :: b
But now it will start deriving types.
We see for instance n <= 0. Now the function (<=) has signature (<=) :: Ord d => d -> d -> Bool. So that means that 0 :: d, and we now that for number literals, it holds that 0 :: Num e => e. So we can add Num a to the type constraint.
We also see null xs, null has signature null :: [f] -> Bool, so that means that a ~ [f] (here ~ means type equality). We also have to check that the expression n <= 0 || null xs results in a Bool (since it is the condition of the if-then-else. Since (||) has as type (||) :: Bool -> Bool -> Bool, it means that n <= 0 and null xs should return Bools. This holds: since (<=) has type Ord d -> d -> Bool, and null :: [f] -> Bool. So after type inference of the first line, we have:
myDrop :: (Num a, Ord a) => a -> [f] -> c
n :: (Num a, Ord a) => a
xs :: [f]
Now we still need to typecheck the second and third line. In an if-then-else clause, the then expression, and else expression need to have the same type, so we now that the type of xs is the same as myDrop (n-1) (tail xs). So even without knowing the signature of myDrop (n-1) (tail xs) we know already that it needs to have type myDrop :: g -> h -> [f] (here we currently do not know the type of g and h.
Since we are deriving the type of myDrop, we can check the type we have constructed thus far, with the one we are calling, so we compare it like:
myDrop :: (Num a, Ord a) => a -> [f] -> c -- currently derived
myDrop :: g -> h -> [f] -- called
So we derive that: a ~ g, and c ~ h ~ [f]. So now we know that myDrop has type:
myDrop :: (Num a, Ord a) => a -> [f] -> [f]
We now still need to typecheck the arguments. We see for instance that the first argument in the call is n - 1, the signature of (-) is (-) :: Num i => i -> i -> i, and 1 is a number literal, so 1 :: Num j => j, so we derive that in this specific context i ~ j ~ a, and as a result n - 1 :: a, thus holds with the derived type for the function.
We also know that tail has signature tail :: [k] -> [k]. Since we call it with xs :: [f], we know that f ~ k, and thus tail xs :: [f], this again holds. We did not had to derive a or f, further, so we can set the type as:
myDrop n xs :: (Num a, Ord a) => a -> [f] -> [f]
Improving the function
The above function works, and it will work regardless what input we provide. But I would call it a bit "unsafe" in the sense that it works because we work with contracts the function we call (tail and null). For example tail will error in case we provide it an empty list. Yes, this can never happen, since null checks this. But we thus have to reason about that ourselves. It is usually better to work only with total functions: functions that always return valid output.
We can here perform pattern matching in the head of the function. A Haskell compiler can derive that we are missing patterns, so if we turn on that feature, then we can validate that all the cases are covered.
We can write it as:
myDrop :: (Num a, Ord a) => a -> [f] -> [f]
myDrop _ [] = []
myDrop n xa#(_:xs) | n <= 0 = xa
| otherwise = myDrop (n-1) xs
So here the first line convers the case where the list is empty (regardless what n is, we return an empty list). In case the list is not empty, it has as pattern (_:xs) (and we also keep a reference to xa, the entire list. In case n <= 0, we return xa, otherwise we decrement n, and make a recursive call on the tail.
You are calling null and tail on xs.
null :: [a] -> Bool
tail :: [a] -> [a]
The arguments to both are lists, so Haskell can infer that, if you are calling null xs or tail xs, the type of xs must be [a].
It doesn't. Haskell doesn't know that xs is a list until it tries to compile the invocation.
When you call myDrop 3 someList Haskell knows that null someList can accept someList, and that tail someList can be called on someList and returns a list. Haskell's (magical) type system can infer (at compile time) how to compile myDrop n xs with what it already knows.
In theory, if you made some "not-list" things that worked for tail and null you could call myDrop 3 notList and get sensible results.
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]
sumoddsquare' :: (Num a) => [a] -> a
sumoddsquare' = sum [x^2 | x <- [1..5], odd x]
My desired output is 35
The syntax error I get is
Couldn't match expected type `[a] -> a'
with actual type `[Integer]'
In the expression: [x ^ 2 | x <- [1 .. 9999], odd x]
In an equation for sumoddsquare':
sumoddsquare' = [x ^ 2 | x <- [1 .. 9999], odd x]
Can you explain this syntax error and also provide a solution for this question?
You've given sumoddsquare' the type Num a => [a] -> a, but you've left off any parameter. Maybe you meant
sumoddsquare' xs = sum [x^2 | x <- xs, odd x]
Although the Num constraint is not sufficient here, inspect the types of ^2 and odd to determine what you should be using. (spoilers below)
Judging by the error message, you've actually defined sumoddsquare' in your code as
sumoddsquare' :: [a] -> a
sumoddsquare' = [x^2 | x <- [1..9999], odd x]
Rather than what you've posted above. Now, you've given the type [a] -> a to sumoddsquares' explicitly, the compiler takes that as a fact, but then it sees the definition. You don't define the argument explicitly in the definition, so the compiler thinks you're defining the function in point-free style. When it sees the right hand side of the =, it gets confused because [x^2 | x <- [1..9999], odd x] has the type [Integer], but it has already accepted the fact that sumoddsquares' has the type [a] -> a. It doesn't know how to reconcile this, so it throws the error you see.
You can usually find the source of these types of error messages by commenting out the explicit type signature. If it then compiles, you can inspect the type in GHCi by doing
> :load sumoddsquare_no_type_sig.hs
> :type sumoddsquare'
[Integer]
And this would tell you that sumoddsquare' is not a function. However, you want it to be a function, so how do you fix this? First, look at the definition. Are all of your arguments declared explicitly? If no, add them.
-- sumoddsquare' :: Num a => [a] -> a
sumoddsquare' xs = [x^2 | x <- [1..9999], odd x]
Then you see
> :reload
> :type sumoddsquare'
[a] -> [Integer]
That's at least a function, but how do we get from the very general type [a] to [Integer]? Since we currently know nothing about a, then this function must not depend on the first argument at all! We can then look through our definition to find where a list might go
-- sumoddsquare' :: Num a => [a] -> a
sumoddsquare' xs = [x^2 | x <- xs, odd x]
-- ^--- This is the only place I saw a list used
Then
> :reload
> :type sumoddsquare'
Integral a => [a] -> [a]
That's closer! We see that the input has been restricted to Integral and we return a more general type than just [Integer]. This tells us we first need to fix the constraint in our type signature from Num a to Integral a. The last puzzle is figuring out how to convert Integral a => [a] into Integral a => a. We want to sum, so now we see that we've left out the sum function in front of the list comprehension
-- sumoddsquare' :: Integral a => [a] -> a
sumoddsquare' xs = sum [x^2 | x <- xs, odd x]
And finally
> :reload
> :type sumoddsquare'
Integral a => [a] -> a
We have a type that matches what we want. We can now uncomment the type signature in our source code.
As a bonus, this problem can be solved entirely with higher order functions as
sumoddsquares' xs = sum $ map (^2) $ filter odd $ xs
-- or point free as
-- sumoddsquares' = sum . map (^2) . filter odd
And in fact, all list comprehensions are just syntactic sugar for maps, filters, and concats. These two pieces of code end up being essentially identical after compilation.