Probably too easy, but I can't find the problem

I’m trying to define a function like this, but something is wrong, and I don’t know why.

nomultiplon :: Int -> [a]

nomultiplon n = [x | x<- [1…1000], x mod n /= 0]

Assuming this is your code:

nomultiplon :: Int -> [a]
nomultiplon n = [x | x <- [1..1000], x `mod` n /= 0]

The function signature says that the function returns [a], a list of any values, but the function returns only whole numbers; it can’t return characters or boolean values; and the compiler complains about it.

Note that a is not a generic type or template parameter as in other languages. it is not a placeholder for any type. a is some type we know nothing about. If we don’t know anything about the type, we can’t do anything with it, so we can’t call mod and it can’t represent a numeric value since the compiler can’t ensure that a is number.

So how does the compiler know. In the function you define a variable x, and since it is the variable returned by the function, it should be of type a. After that you call mod x n. Here is the signature of mod:

mod :: Integral b => b -> b -> b

mod takes two parameters of type b where b is an integral type. But your variable x is of some type a, so the compiler doesn’t know if a is an integral type or not and rejects the code.

Now as the second parameter you apply n to mod. n has the type Int and Int is an integral type. Because mod takes 2 bs and returns a b, and n is an Int, the compiler can infer that b is an Int. and the type of mod becomes:

mod :: Int -> Int -> Int

And it doesn’t work with a as well since the compiler doesn’t know whether a is an Int or not.

Since both, x and n are applied to mod and become b in the mod signature, they should have the same type and be instances of Integral, so we get:

nomultiplon :: Int -> [Int]
nomultiplon n = [x | x <- [1..1000], x `mod` n /= 0]

or more generic:

nomultiplon :: Integral a => a -> [a]
nomultiplon n = [x | x <- [1..1000], x `mod` n /= 0]

Thank you very much for the exhaustive and clear explanation.