Ambiguous type variable `a0' arising from a use of `print'? - haskell

While learning Haskell I'm trying to write a function that given a number will give its successor in a Collatz sequence:
next :: (Fractional a, Integral a) => a -> a
next x
| odd x = x * 3 + 1
| otherwise = x / 2
When I run next 7 I get:
<interactive>:150:1: error:
* Ambiguous type variable `a0' arising from a use of `print'
prevents the constraint `(Show a0)' from being solved.
Probable fix: use a type annotation to specify what `a0' should be.
These potential instances exist:
instance Show Ordering -- Defined in `GHC.Show'
instance Show Integer -- Defined in `GHC.Show'
instance Show a => Show (Maybe a) -- Defined in `GHC.Show'
...plus 22 others
...plus 12 instances involving out-of-scope types
(use -fprint-potential-instances to see them all)
* In a stmt of an interactive GHCi command: print it
Two questions:
Am I using the best class constraints in my signature?
Assuming I am, how can I show the result of next 7 ?

I believe Collatz sequence is an integer sequence, so it wouldn't be necessary making the result Fractional.
next :: (Integral a) => a -> a
To be able to get an integer from a division, you should use div function. Note that division will always be exact as you are going to divide only even numbers:
next x
| odd x = x * 3 + 1
| otherwise = x `div` 2

Related

Problem when defining Int as an instance of a type class in Haskell

I am trying to define Int as an instance of my type class Add.
I wanted to define my own operator +++, which should be overloaded on integers and strings. My goal was to be able to add integers and concatenate strings with the same operator. Therefore i created the type class Add with the instances Int and [char]:
class Add a where
(+++) :: a -> a -> a
instance Add Int where
x +++ y = x + y
instance Add [char] where
x +++ y = x ++ y
Problem: When evaluating the expression 1 +++ 2, GHCi gives me the following error message:
<interactive>:9:1: error:
• Ambiguous type variable ‘a0’ arising from a use of ‘print’
prevents the constraint ‘(Show a0)’ from being solved.
Probable fix: use a type annotation to specify what ‘a0’ should be.
These potential instances exist:
instance Show Ordering -- Defined in ‘GHC.Show’
instance Show Integer -- Defined in ‘GHC.Show’
instance Show a => Show (Maybe a) -- Defined in ‘GHC.Show’
...plus 22 others
...plus 18 instances involving out-of-scope types
(use -fprint-potential-instances to see them all)
• In a stmt of an interactive GHCi command: print it
But when defining Integer as an instance of Add
instance Add Integer where
x +++ y = x + y
GHCi can evaluate 1 +++ 2 to 3 and i don't get an error.
Question: Why is it not working, when using Int as an instance? What is the difference in using Int or Integer?
Given that it works for Integer but not Int, I'm fairly sure this is due to "type defaulting".
In GHCi (and to a lesser extent in compiled code), if an expression has an ambiguous type, the compiler tries several "default types", which of which is Integer (but not Int). That's almost certainly where the difference is coming from.
I suspect if you add :: Int to the end of your expression, it will execute just fine. The problem isn't that there's a type error, it's that more than one type potentially fits, and the compiler isn't sure which one you intended.
I've never tried this, but I believe you can change the defaults by saying something like default (Int, Double). (Usually it's default (Integer, Double).) I think that's the right syntax; not 100% sure.
There's a bit about this in the GHCi manual: https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/ghci.html#type-defaulting-in-ghci
Also the Haskell Report: https://www.haskell.org/onlinereport/haskell2010/haskellch4.html#x10-750004.3 (Section 4.3.4)

Why does multiplesOf num max = [num*k | k <- [1..floor (max/num)]] throw an error?

I am trying to create a set of all the multiples of a number num under an upper limit max. I have written the following function in Haskell:
multiplesOf num max = [num*k | k <- [1..floor (max/num)]]
Why does this function throw the following error during run-time and how can it be fixed?
<interactive>:26:1: error:
• Ambiguous type variable ‘a0’ arising from a use of ‘print’
prevents the constraint ‘(Show a0)’ from being solved.
Probable fix: use a type annotation to specify what ‘a0’ should be.
These potential instances exist:
instance Show Ordering -- Defined in ‘GHC.Show’
instance Show Integer -- Defined in ‘GHC.Show’
instance Show a => Show (Maybe a) -- Defined in ‘GHC.Show’
...plus 22 others
...plus 18 instances involving out-of-scope types
(use -fprint-potential-instances to see them all)
• In a stmt of an interactive GHCi command: print it
This error was thrown when, for example, entering multiplesOf 3 1000.
There is no error in defining the function. The error is more when you want to use the function.
If we take a look at the type of the function you have constructed, we see:
multiplesOf :: (RealFrac t, Integral t) => t -> t -> [t]
So here the type of input and output values should both be Integral, and RealFrac. So that means that number should be Integral, but at the same time support real division. There are not much types that would fit these requirements.
This problem arises from the fact that you use (/) and floor here, which hints that max and num are RealFracs, but the result of floor is an Integral, and then you mulitply numbers out of this range again with num.
You can however reduce the amount of type constraints, by making use of div :: Integral a => a -> a -> a. This is thus integer division, and the result is truncated towards negative infinity, so we can implement the function like:
multiplesOf :: Integral i => i -> i -> [i]
multiplesOf num max = [num*k | k <- [1..div max num]]
or we can even save us the trouble of making divisions, multiplications, etc. and work with a range expression that does the work for us:
multiplesOf :: (Num n, Enum n) => n -> n -> [n]
multiplesOf num max = [num, (num+num) .. max]
The latter is even less constraint, since Integral i implies Real i and Enum i.

Haskell - Signature and Type error

I'm new to Haskell and I'm having some trouble with function signature and types. Here's my problem:
I'm trying to make a list with every number between 1 and 999 that can be divided by every numeral of it's own number. For example the number 280 can be in that list because 2+8+0=10 and 280/10 = 28 ... On the other hand 123 can't because 1+2+3=6 and 123/6=20,5. When the final operation gives you a number with decimal it will never be in that list.
Here's my code:
let inaHelper x = (floor(x)`mod`10)+ (floor(x/10)`mod`10)+(floor(x/100)`mod`10)
This first part will only do the sum of every numeral of a number.
And this part works...
Here's the final part:
let ina = [x | x <- [1..999] , x `mod` (inaHelper x) == 0 ]
This final part should do the list and the verification if it could be on the list or not. But it's give this error:
No instance for (Integral t0) arising from a use of ‘it’
The type variable ‘t0’ is ambiguous
Note: there are several potential instances:
instance Integral Integer -- Defined in ‘GHC.Real’
instance Integral Int -- Defined in ‘GHC.Real’
instance Integral Word -- Defined in ‘GHC.Real’
In the first argument of ‘print’, namely ‘it’
In a stmt of an interactive GHCi command: print it
...
ina = [x | x <- [1..999] , x `mod` (inaHelper x) == 0 ]
What is the type of x? Integer? Int? Word? The code above is very generic, and will work on any integral type. If we try to print its type we
get something like this
> :t ina
ina :: (Integral t, ...) => [t]
meaning that the result is a list of any type t we want, provided t is an integral type (and a few other constraints).
When we ask GHCi to print the result, GHCi needs to choose the type of x, but can not decide unambiguously. This is what the error message states.
Try specifying a type when you print the result. E.g.
> ina :: [Int]
This will make GHCi choose the type t to be Int, removing the ambiguity.

Why can't Haskell function return a list

What is wrong with that:
partin a = [floor a, a-floor a]
Error :
<interactive>:342:1: error:
• Ambiguous type variable ‘a0’ arising from a use of ‘print’
prevents the constraint ‘(Show a0)’ from being solved.
Probable fix: use a type annotation to specify what ‘a0’ should be.
These potential instances exist:
instance Show Ordering -- Defined in ‘GHC.Show’
instance Show Integer -- Defined in ‘GHC.Show’
instance Show a => Show (Maybe a) -- Defined in ‘GHC.Show’
...plus 22 others
...plus 16 instances involving out-of-scope types
(use -fprint-potential-instances to see them all)
• In a stmt of an interactive GHCi command: print it
I can't give a complete answer without seeing the full extent of what you're doing, but here's one definite problem that is almost certainly involved. You write
partin a = [floor a, a-floor a]
The type of floor is
floor :: (RealFrac a, Integral b) => a -> b
The type of (-) is
(-) :: Num a => a -> a -> a
Since you use a - floor a, you're forcing the type of a to be an instance of both the RealFrac class and the Integral class. However, there is no such type in the standard library (and it doesn't make a lot of sense). As a result, GHC certainly will not be able to select the type for you from its very limited collection of defaults. Things might work out a lot better if you use
partin a = [fromIntegral (floor a), a - fromIntegral (floor a :: Int)]
But note that it doesn't really make much sense to have a list here, since you're trying to divide a number into two components of different types. You might be better off with
partin a = (floor a, a - fromIntegral (floor a :: Int))

Why does the operator ** fail where the operator ^ works?

So, here are two list comprehensions, first uses ^ while second uses **:
> [x ^ 2 | x <- [1..10], odd x]
[1,9,25,49,81]
> [x ** 2 | x <- [1..10], odd x]
<interactive>:9:1:
No instance for (Show t0) arising from a use of ‘print’
The type variable ‘t0’ is ambiguous
Note: there are several potential instances:
instance Show Double -- Defined in ‘GHC.Float’
instance Show Float -- Defined in ‘GHC.Float’
instance (Integral a, Show a) => Show (GHC.Real.Ratio a)
-- Defined in ‘GHC.Real’
...plus 23 others
In a stmt of an interactive GHCi command: print it
As far as I know difference between the two operators is that first works with integers, while second works with floating point values. Expected output then:
[1.0,9.0,25.0,49.0,81.0]
Actual question is: why does the second list comprehension fail?
As you say ** works with floating ponints. However odd only works with Integrals. Therefore your second list comprehension only works with types that are instances of both Floating and Integral and such a type does not exist.
However I'm not sure why the error message claims that there are 26 possible instances when none of the instances it mentions actually meet the required constraints.

Resources