No instance for (Integral [t0]) error in Haskell code - haskell

I'm getting an error:
No instance for (Integral [t0]) when I run this haskell code.
boomBangs xs = [(a,b,c) |a<-[1..xs],b<-[1..xs],c<-[1..xs], xs <- xs `div` 2]
Where am I going wrong?

The problem is that you're trying to divide a list. In particular, xs `div` 2 is the incorrect expression.
You can get this from the error message: it's complaining that [t0] does not behave like an integer (e.g. it isn't in the Integral class). [t0] is just a list of stuff--the t0, being in lowercase, is a type variable that represntes any type.
Since lists of stuff aren't numbers, we can't really know how to divide them.
You can see why you get this exact error message by looking at the type of div:
div :: Integral i => i -> i -> i
All this means is that given some type i in the Integral class, you can divide two of them together to get a third. Since lists of things are not part of the integral class, you can't divide them and so you get an error.
If div had a concrete type like div :: Int -> Int -> Int, you would get an error telling you that it can't match the expected type Int with the actual type [t0]. However, since the type actually contains a variable i, the error is a bit more complex: [t0] cannot be a valid type to use in place of i because it is not in the Integral class.

What you said was:
Give me a tuple of a, b, and c:
[ (a, b, c)
For each a, b, and c in the list of values from 1 to xs1:
| a <- [1..xs1]
, b <- [1..xs1]
, c <- [1..xs1]
For each xs2 in the quotient of xs1 and 2.
, xs2 <- xs1 `div` 2
]
If you compile with warnings enabled (-Wall) or turn them on in GHCi (:set -Wall) then you’ll get a warning that the xs in xs <- ... shadows the xs in boomBangs xs = ..., and also that it’s unused. Obviously this kind of warning can be very helpful, as it points right to your problem.
Since xs1 is the input to your function, you end up with a type like this:
(Integral [t]) => [t] -> [([t], [t], [t])]
Which is to say that the function takes a list (xs1) that can act as a number ((`div` 2)) and gives you back a list of tuples of such lists. Even though you’re trying to divide a list by a number, GHC allows it and infers a more general type because you could have defined an Integral instance for lists. It only discovers that you haven’t when you actually try to use the function on a concrete type. Writing down type signatures can help keep the compiler grounded and give you better error messages.
I can only guess you meant for boomBangs to have a type like:
Integral t => [t] -> [(t, t, t)]
Or just:
[Int] -> [(Int, Int, Int)]
In which case maybe you were thinking of something like this:
[ (a, b, c)
| x <- xs
, a <- [1..x `div` 2]
, b <- [1..x `div` 2]
, c <- [1..x `div` 2]
]

Related

What does " Non type-variable argument in the constraint" really mean?

For example:
map (+1) 2
in ghci yields
<interactive>:23:1: error:
* Non type-variable argument in the constraint: Num [b]
(Use FlexibleContexts to permit this)
* When checking the inferred type
it :: forall b. (Num b, Num [b]) => [b]
I've seen many questions similar to mine, but all seem only to answer what we can deduce from this (that the type of the second argument to map is wrong), and how to fix it - but not what error actually means . Where do things go wrong precisely?
The error arises during the type-deduction of your statement.
Since
(+1) is of type Num a => a -> a
2 is of type Num a => a
map is of type (a -> b) -> [a] -> [b]
We know that map (+1) has to be of type (Num b) => [b] -> [b], and therefore map (+1) 2 of type (Num b, Num [b]) => [b]. But [b] is not just a type-variable, it's List of some type variable, where list is a data constructor. In an alternative version of Haskell where no syntactic sugar for lists exists, we might write (Num b, Num (List b)).
This is a problem because by default, Haskell does not support non type-variable arguments for constraints. So the precise nature of the problem is not that Haskell doesn't know how to map over numbers - it's that it doesn't allow values of the type that our function call produces.
But that rule isn't strictly needed. By adding -XFlexibleContexts when calling ghci, types of the sort that our method produces are now allowed. The reason for this is that the literal 2 in Haskell doesn't really represent a number - it represents an object of type Num a => a, which is constructed from the Integral 2 using fromIntegral. So the statement map (+1) 2 is equivalent to map (+1) (fromIntegral (2::Integer)). This means that the literal "2" can represent anything, given the proper instantiation - including lists.
2 has the type Num a => a; we haven't specified what a is, except that it has to have a Num instance.
map (+1) has the type Num b => [b] -> [b]; we have specified what b is, except it has to have a Num instance.
When we determine the type of map (+1) 2, we are basically unifying Num a ~ Num b => [b].
2 :: Num a => a
map (+1) :: Num b => [b] -> [b]
map (+1) 2 :: (Num b, Num [b]) => [b]
And this is the problem. Num requires a type variable like a or b, not a polymorphic type like [b], as its argument.
Here’s an actual answer:
GHC tries to infer the types by itself, and failed, or in GHC lingo:
When checking the inferred type …
Basically the conflict is:
• GHC is happy to have any value as a parameter for map (+1), as long as it is compatible with its type. And map (+1) wants a list of numbers, since + wants two numbers and 1 already is one number, and map always wants a list of values compatible with that.
• And here’s the kicker: GHC is happy to have 2 be any type! Because to save you the hassle of always having to specify if a literal 2 is of a certain type, GHC just treats numeric literals as Integer and replaces it with fromInteger 2. So since fromInteger is from the class Num, 2 can be anything that implemented that class Num! So 2 could be a list too!
So GHC is stuck trying to fit those things together, and tells you:
“It needs to be some value, that is a number. … And where the list of those values is also a number!”
Or in Haskell:
it :: forall b. (Num b, Num [b]) => [b]
But there is no instance that makes lists numbers!
Or in GHC lingo:
Non type-variable argument in the constraint: Num [b]
That’s why you nowadays get this, yes definitely badly designed and confusing error message.
(Almost all GHC error messages are a cruel joke. The best thing you can do to understand them, is to read them bottom to top! And know all of Haskell’s type system freedoms and the GHC extensions that are forcing GHC to not make assumptions that would make these errors a much simpler sub-class of errors otherwise.)
Obviously, you’d normally just replace 2 with an actual list of some sort. But we’re not going to do that here. Since GHC wants crazy, GHC shall get crazy:
Silly resolution
So since it leaves us the option of making lists (of numbers) numbers, that’s what we shall do:
instance Num b => Num [b] where
(+) = zipWith (+)
(*) = zipWith (*)
abs = map abs
signum = map signum
fromInteger i = [fromInteger i]
-- or repeat [fromInteger i], if we’re evil. ;)
negate = map negate
So now, it works perfectly fine:
> map (+1) 2
[3]
Since 2 becomes fromInteger 2 :: Num a => [a], which puts 2 in a list ([2]), and then map (+1) is happy and turns it into [2+1]. Which evaluates to [3].
This possibility is why the error message wasn’t a much simpler
“Error: 2 is not a list, but map expects a list!”.

The case of the disappearing constraint: Oddities of a higher-rank type

All the experiments described below were done with GHC 8.0.1.
This question is a follow-up to RankNTypes with type aliases confusion. The issue there boiled down to the types of functions like this one...
{-# LANGUAGE RankNTypes #-}
sleight1 :: a -> (Num a => [a]) -> a
sleight1 x (y:_) = x + y
... which are rejected by the type checker...
ThinAir.hs:4:13: error:
* No instance for (Num a) arising from a pattern
Possible fix:
add (Num a) to the context of
the type signature for:
sleight1 :: a -> (Num a => [a]) -> a
* In the pattern: y : _
In an equation for `sleight1': sleight1 x (y : _) = x + y
... because the higher-rank constraint Num a cannot be moved outside of the type of the second argument (as would be possible if we had a -> a -> (Num a => [a]) instead). That being so, we end up trying to add a higher-rank constraint to a variable already quantified over the whole thing, that is:
sleight1 :: forall a. a -> (Num a => [a]) -> a
With this recapitulation done, we might try to simplify the example a bit. Let's replace (+) with something that doesn't require Num, and uncouple the type of the problematic argument from that of the result:
sleight2 :: a -> (Num b => b) -> a
sleight2 x y = const x y
This doesn't work just like before (save for a slight change in the error message):
ThinAir.hs:7:24: error:
* No instance for (Num b) arising from a use of `y'
Possible fix:
add (Num b) to the context of
the type signature for:
sleight2 :: a -> (Num b => b) -> a
* In the second argument of `const', namely `y'
In the expression: const x y
In an equation for `sleight2': sleight2 x y = const x y
Failed, modules loaded: none.
Using const here, however, is perhaps unnecessary, so we might try writing the implementation ourselves:
sleight3 :: a -> (Num b => b) -> a
sleight3 x y = x
Surprisingly, this actually works!
Prelude> :r
[1 of 1] Compiling Main ( ThinAir.hs, interpreted )
Ok, modules loaded: Main.
*Main> :t sleight3
sleight3 :: a -> (Num b => b) -> a
*Main> sleight3 1 2
1
Even more bizarrely, there seems to be no actual Num constraint on the second argument:
*Main> sleight3 1 "wat"
1
I'm not quite sure about how to make that intelligible. Perhaps we might say that, just like we can juggle undefined as long as we never evaluate it, an unsatisfiable constraint can stick around in a type just fine as long as it is not used for unification anywhere in the right-hand side. That, however, feels like a pretty weak analogy, specially given that non-strictness as we usually understand it is a notion involving values, and not types. Furthermore, that leaves us no closer from grasping how in the world String unifies with Num b => b -- assuming that such a thing actually happens, something which I'm not at all sure of. What, then, is an accurate description of what is going on when a constraint seemingly vanishes in this manner?
Oh, it gets even weirder:
Prelude> sleight3 1 ("wat"+"man")
1
Prelude Data.Void> sleight3 1 (37 :: Void)
1
See, there is an actual Num constraint on that argument. Only, because (as chi already commented) the b is in a covariant position, this is not a constraint you have to provide when calling sleight3. Rather, you can just pick any type b, then whatever it is, sleight3 will provide a Num instance for it!
Well, clearly that's bogus. sleight3 can't provide such a num instance for strings, and most definitely not for Void. But it also doesn't actually need to because, quite like you said, the argument for which that constraint would apply is never evaluated. Recall that a constrained-polymorphic value is essentially just a function of a dictionary argument. sleight3 simply promises to provide such a dictionary before it actually gets to use y, but then it doesn't use y in any way, so it's fine.
It's basically the same as with a function like this:
defiant :: (Void -> Int) -> String
defiant f = "Haha"
Again, the argument function clearly can not possibly yield an Int because there doesn't exist a Void value to evaluate it with. But this isn't needed either, because f is simply ignored!
By contrast, sleight2 x y = const x y does kinda sorta use y: the second argument to const is just a rank-0 type, so the compiler needs to resolve any needed dictionaries at that point. Even if const ultimately also throws y away, it still “forces” enough of this value to make it evident that it's not well-typed.

Type Specification in a Where Clause

I'm trying to do something very simple as part of a homework. All I need to do is write a function that takes in a list of 2-tuples of numbers representing base and height lengths for triangles, and return a list of the areas corresponding to those triangles. One of the requirements is that I do that by defining a function and declaring its type in a where clause. Everything I've tried so far fails to compile, here's what I've got:
calcTriangleAreas xs = [triArea x | x<-xs]
where triArea:: (Num, Num) -> Num --this uses 4 preceding spaces
triArea (base, height) = base*height/2
This fails with the error The type signature for ‘triArea’ lacks an accompanying binding, which to me sounds like triArea is not defined inside of the where-clause. Okay, so let's indent it to match the where:
calcTriangleAreas xs = [triArea x | x<-xs]
where triArea:: (Num, Num) -> Num --this uses 4 preceding spaces
triArea (base, height) = base*height/2 --... and so does this
This one fails to compile the particularly uninformative error message parse error on input triArea. Just for fun, let's try indenting it a bit more, because idk what else to do:
calcTriangleAreas xs = [triArea x | x<-xs]
where triArea:: (Num, Num) -> Num --this uses 4 preceding spaces
triArea (base, height) = base*height/2 --this has 8
but, no dice, fails with the same parse error message. I tried replacing the spacing in each of these with equivalent, 4-space tabs, but that didn't
help. The first two produce the same errors with tabs as with spaces, but the last one, shown here:
calcTriangleAreas xs = [triArea x | x<-xs]
where triArea:: (Num, Num) -> Num --this uses a preceding tab character
triArea (base, height) = base*height/2 --this has 2
gives the error message
Illegal type signature: ‘(Num, Num) -> Num triArea (base, height)’
Perhaps you intended to use ScopedTypeVariables
In a pattern type-signature
and I have no idea what that's trying to say, but it seems to be ignoring newlines all of a sudden. I've been reading through "Learn You a Haskell", and I'm supposed to be able to do this with the information presented in the first three chapters, but I've scoured those and they never specify the type of a functioned defined in a where clause in those chapters. For the record, their examples seem to be irreverent of spacing, and I copied the style of one of them:
calcTriangleAreas xs = [triArea x | x<-xs]
where triArea:: (Num, Num) -> Num --4 preceding spaces
triArea (base, height) = base*height/2 --10 preceding spaces
but this also failed to compile, spitting out the utterly incomprehensible error message:
Expecting one more argument to ‘Num’
The first argument of a tuple should have kind ‘*’,
but ‘Num’ has kind ‘* -> GHC.Prim.Constraint’
In the type signature for ‘triArea’: triArea :: (Num, Num) -> Num
In an equation for ‘calcTriangleAreas’:
calcTriangleAreas xs
= [triArea x | x <- xs]
where
triArea :: (Num, Num) -> Num
triArea (base, height) = base * height / 2
I can't find anything when I google/hoogle it, and I've looked at this question, but not only is it showing haskell far too
advanced for me to read, but based on the content I don't believe they're having the same problem as me. I've tried specifying the type of calcTriangleAreas, and I've tried aliasing the types in the specification for triArea to be Floating and frankly I'm at the end of my rope. The top line of my file is module ChapterThree where, but beyond that the code I've shown in every example is the entire file.
I'm working on 32-bit Linux Mint 18, and I'm compiling with ghc ChapterThree.hs Chapter3UnitTests.hs -o Test, where ChapterThree.hs is my file and the unit tests are given by my teacher so I can easily tell if my program works (It never gets to the compilation step for ChapterThreeUnitTests.hs, so I didn't think the content would be important), and my ghc version is 7.10.3.
EDIT: Note that if I just remove the type specification altogether, everything compiles just fine, and that function passes all of its associated unit tests.
Please, save me from my madness.
Your last example is correct, but the type you wrote doesn't make sense. Num is a class constraint not a type. You probably wanted to write:
calcTriangleAreas xs = [triArea x | x<-xs]
where triArea:: Num a => (a, a) -> a
triArea (base, height) = base*height/2
The rule is: assignments must be aligned.
Moreover (/) requires the Fractional class:
calcTriangleAreas xs = [triArea x | x<-xs]
where triArea:: Fractional a => (a, a) -> a
triArea (base, height) = base*height/2
Note that the indentation level is not related in any way with the indentation level of the where. For example you could write that code in this way:
calcTriangleAreas xs = [triArea x | x<-xs] where
triArea:: Fractional a => (a, a) -> a
triArea (base, height) = base*height/2
The indentation level is defined by the first assignment in a where/let or the first line of a do block. All the other lines must align with that one.
So all of these are correct:
f x = y where
a = b
y = ...
f x = y
where a = b
y = ...
f x = y
where
a = b
y = ...
spitting out the utterly incomprehensible error message:
Expecting one more argument to ‘Num’
The first argument of a tuple should have kind ‘*’,
but ‘Num’ has kind ‘* -> GHC.Prim.Constraint’
To complement Bakuriu's answer, let me decode that for you.
The error says that -- line by line:
Num is expecting one more argument -- we should write Num a from some a
A tuple type such as (,) expects a type as argument. The statement "should have kind *" means "should be a type". The kinding system of Haskell associates * as the "kind of types". We have e.g. Int :: *, String :: *, and (Maybe Char, [Int]) :: *. Unary type constructors such as Maybe and [] are not types, but functions from types to types. We write Maybe :: *->* and [] :: *->*. Their kind *->* makes it possible to state that, since Maybe :: *->* and Char :: *, we have Maybe Char :: * ("is a type") similarly to ordinary value-level functions. The pair type constructor has kind (,) :: *->*->*: it expects two types and provides a type.
Num has kind *-> Constraint. This means that, for every type T, the kind of Num T will be Constraint, which is not * as (,) expects. This triggers a kind error. The kind Constraint is given to typeclass constraints such as Eq Int, Ord Bool, or Num Int. These are not types, but are requirements on types. When we use (+) :: Num a => a->a->a we see that (+) works on any type a, as long as that type satisfies Num a, i.e. is numeric. Since Num T is not a type, we can not write Maybe (Num T) or [Num T], we can only write e.g. Maybe a and require in the context that a belongs to typeclass Num.

Execution order of list comprehension filtering

Just started learning Haskell and came across this issue.
If I have a list comprehension with a condition such as
[x*2 | x<- [1..10], x `mod` 3 ==2]
I get
[4,10,16]
as expected. However, if I have instead
[x**2 | x<- [1..10], x `mod` 3 ==2]
It is has the type variable as ambiguous for the mod function. I presume this is because x2 promotes an integer to a float, but why does this affect the conditional? Why is the type ambiguous in this case? Does it calculate x2, and then square root it? (This seems highly improbable) Does it somehow keep track of the x that generated each x2 term?
Perhaps it's the imperative mindset, but internally, I thought the execution would be along the lines of [in python]
lst=[]
for x in range(10):
if x%3==2:
lst.append(x**2)
Could someone clarify/correct my understanding?
Let's have a look at the types of mod and (**):
mod :: Integral n => n -> n -> n
(**) :: Floating a => a -> a -> a
-- hm......
mod and (**) put other constraints on the used type. mod expects an integral type (Int, Integer), whereas (**) expects a floating type (Float, Double). Since there's no type that's both integral and a floating point number, GHC gives up.
Instead, use (^):
(^) :: (Integral n, Num a) => a -> n -> a
E.g.
[x ^ 2 | x <- [1..10], x `mod` 3 == 2]
By the way, you can find errors like this easier if you try to give a type to the result:
ghci> [x ** 2 | x <- [1..10], x `mod` 3 == 2] :: [Int]
<interactive>:1:4:
No instance for (Floating Int) arising from a use of `**'
In the expression: x ** 2
...
The first example works because of defaulting. The expression is inferred as having type
Integral a => [a]
and then the a type variable is defaulted to Integer for convenience.
In the second expression, the use of ** forces x to be Floating and the mod forces it to be Integral. So GHC infers that the expression has type
(Integral a, Floating a) => [a]
There is no standard numeric type that is both Integral and Floating, let alone one that participates in defaulting.
You mentioned the notion of numeric promotion in your question. C, C++, Java, and maybe some other languages have such a thing. Haskell does not, and those of us who use it tend to be grateful for that. All conversions from one numeric type to another have to be done using explicit conversion functions like fromIntegral, fromRational, round, floor, %, etc.
You probably meant to use ^ instead of **, which would leave just the Integral a constraint. In a real program, you should generally avoid the defaulting mechanism by including a type signature. You can turn it off altogether using
default ()
somewhere in your module.
List comprehension in haskell desugars to a do-block using the list monad. In your example, it would be something like:
x <- [1..10]
guard $ (x `mod` 3) == 2
return $ x**2
In this case it attempts to unify the types of (**) x 2 and mod x 3 which fails because you can't unify a Floating type with an Integral type without explicitly converting between the two.
You've got a few options: use (^^) instead of (**) or do ((fromIntegral x) ** 2) if you want x to be an integral type, or somehow round x to an integral type if you want it to be a floating type.

Couldn't match expected type error

As a beginner, I was working on item number 3 of the Haskell 99 problems. The first code snippet is my solution. However, I cannot add the type declaration of [a] -> Int -> a.
It produces an error: Couldn't match type 'a' with 'Int'
--My Solution
--elementAt :: [a] -> Int -> a
elementAt xs num = head . reverse $ takeWhile (<num+1) xs
Meanwhile, one of the solution in the problem 3 works perfectly with the same output.
elementAt' :: [a] -> Int -> a
elementAt' list i = list !! (i - 1)
I've used the :type in the GHCI for the elementAt without the declaration and it shows:
elementAt :: (Num c, Ord c) => [c] -> c -> c
What is the difference of the two functions?
takeWhile (<num+1) xs says that you want to take elements at the front of the list xs while the element (not the index!) is less than num + 1. Since you're comparing num (which is an Int) with the list elements, the compiler infers that the list elements have to be Int as well, which contradicts your type declaration.
Without the type declaration, GHC infers that xs's elements and num have to be the same type (since you compare list elements with num). This type has to have an Ord instance (for the comparison) as well as a Num instance (because of the addition).
The type of takeWhile (< num + 1) is [Int] -> [Int].
However the type of xs is [a].
Essentially you are trying to apply a predicate Int -> Bool to elements of type a.
If you want to filter based on the position in the list, you first need to augment the input list with the position of each element. You can do this fairly easily with zip:
zip xs [1..]
You can then drop elements based on the value of the second element of the resulting list.

Resources