
On Mon, 2008-04-21 at 22:58 -0700, Jonathan Cast wrote:
class Forceable alpha where seq :: alpha -> beta -> beta
Instances derived automatically by the compiler, when possible, for every type (like Typeable should be). We can omit functions if desired (I don't remember why I thought this was a good idea). When you say
f :: alpha -> beta
or
f :: C alpha => alpha -> beta
The compiler adds implicit Forceable constraints on alpha and beta. But, if you say
f :: !Forceable alpha => alpha -> beta
The compiler leaves the Forceable alpha constraint off. Then you can say
build :: (forall c. !Forceable c => (a -> c -> c) -> c -> c) -> [a]
And the foldr/build law is still sound.
Why do you want types that lie, plus some crazy ad-hoc special case? Why not just let f :: a -> b mean what you write as f :: !Forceable a => a -> b exactly as it would if seq were moved (back) into a class? Then the free theorems would hold for the types as stated.