Making a library such as cadsim, one encounters the need to provide functions that accept numbers. For example, consider a function like this one:

-- |Moves pointer left, drawing a line

left :: (Convertible a Double) => a -> PathBuild ()

The logic being that I could perhaps take any input that would have an instance. This would let me create instances for say Int, Double, Float. But this would also let me create instances for newtype types that have an explicit unit.

For example:

For example:

newtype MM = MM Double

mm = MM

class Convertible a where

conv :: a -> Double

instance Convertible MM where

conv (MM n) = n

instance Convertible Int where

conv = realToFrac

left (mm 35) -- works

left 35 -- error!

The last entry wont work!

Ambiguous type variable `a0' in the constraints:

(Num a0) arising from the literal `1' at :0:6

(Conv a0) arising from a use of `left' at :0:1-4

Probable fix: add a type signature that fixes these type variable(s)

In the first argument of `left', namely `1'

In the expression: left 1

In an equation for `it': it = left 1

Why not? The message is quite explanatory, albeit cryptic.

To find out, lets fire up ghci and see what it thinks about the types of the last line.

To find out, lets fire up ghci and see what it thinks about the types of the last line.

GHCi, version 7.2.2: http://www.haskell.org/ghc/ :? for help

.....

[1 of 1] Compiling Main ( test.hs, interpreted )

Ok, modules loaded: Main.

*Main> :t left

left :: Conv a => a -> Double

*Main> :t 3

3 :: Num a => a

Aha! So ghc knows 3 is of type Num a, but cannot

*default*to Int. That seems reasonable. We could have wildly different implementations of a typeclass for Int and Double (say for serializing them to a file) and when presented with a literal, ghc shouldn’t automagically choose some arbitrary type.But it

*does*exactly that today with Show!!

*Main> :t show

show :: Show a => a -> String

*Main> show 3

"3"

Whats going on! Looks like some typeclasses default to some instance, while others aren’t. The rules for the special defaulting in GHC can be found here.

Here’s a discussion about this topic on StackOverflow which explains why Show and Num play well together, but other “external” type classes don’t(i.e. they need the type to be explicitly specified).