Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to force a type to a class in Haskell?

As an example, say I wish to implement a function which sums up a list of Nums. Halfway through coding it, I wish to debug it with Debug.Trace:

module T where
import Debug.Trace

dosum :: (Num a) => [a] -> a
dosum xs = dosum' 0 xs
    where
        dosum' n [] = n
        dosum' n (x:xs) = trace (show n) $ dosum' (n+x) xs

The problem is that this will not compile:

Could not deduce (Show a) arising from a use of dosum'
from the context (Num a)

I can add (Show a) to dosum and then remove it when I am finished debugging (in real life, I will want to have a type which is not necessarily in Show, but I will debug with integers). This can get cumbersome if there are a few functions involved and I keep adding removing Show a statements.

I want to have a function unsafeShow

unsafeShow :: a -> String

which works if a is Show a and is free to crash if it is not. Is this possible?

like image 549
luispedro Avatar asked Apr 18 '12 14:04

luispedro


1 Answers

No, this is not possible. It would violate parametricity; a polymorphic function is not allowed to behave differently based on the specific type it is called with. It would also break the open world assumption, in that adding a Show instance for a type would change the behaviour of your program.

It could be a useful debugging aid, as something explicitly marked unsafe, but GHC does not support such a function, and I don't think its current implementation would permit the easy addition of one.

A possible alternative, if you have many functions with the same typeclass context that you want to do this with, and there is a conceptual semantic grouping to, would be to have a class like

class (Num a) => Number a
instance (Num a) => Number a

which you can use instead of Num in signatures, changing the declaration to (Num a, Show a) when debugging. (It would be better to pick a more meaningful name than Number, however!)

like image 83
ehird Avatar answered Sep 21 '22 11:09

ehird