On 22 Apr 2008, at 8:03 PM, Derek Elkins wrote:
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.

See /Being Lazy with Class/, on why seq was made polymorphic in the first place. I don't /want/ this design, but the most common case is that you don't care, for a type variable alpha, whether seq can be used on alpha or not. When you do care, the most common case is that you want seq, and adding seq where it wasn't previously legal requires a chain of modifications reminiscent of const poisoning. I'm willing to consider seq :: a -> b -> b a practical necessity, and compromise with it, as long as I can still declare properly parametric types on command.

jcc

PS ‘Lie’ is a bit strong. A lie is a statement crafted to have a meaning not in the belief set of the speaker. The meaning of a Haskell type judgement is given by the language. So

square :: Num alpha => alpha -> alpha
square x = x ** 2

contains a lie.  But I don't think seq :: alpha -> beta -> beta 
does._______________________________________________
Haskell-Cafe mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to