{-# LANGUAGE NoMonomorphismRestriction #-}
Or if you want something less global
let quux () = bar undefined in
print (idInt (quux ()) >> print (idChar (quux ()))
The reason the latter works is that bindings are only monomorphised when they have no arguments to the left of the equals sign.
let foo = \x y -> x + y -- :: Integer -> Integer -> Integer
let bar x y = x + y -- :: (Num a) => a -> a -> a
So to get quux
to not monomorphize, you have to give it an argument to the left of the equals sign. If quux
is not a value but a function, you can simply eta expand to get the same effect:
let quux x = bar undefined x in ...
For the former, don't worry about performance -- if you always call it as quux ()
, then it will be inlined and generate the same code as the version with an explicit type signature.