# deriving over renamed types

**Pixel
**
pixel@mandrakesoft.com

*09 Apr 2002 01:05:45 +0200*

Ashley Yakeley <ashley@semantic.org> writes:
[...]
>* -- which of these types are the same?
*>* f1 = MkFoo undefined :: Foo Succ;
*>* f2 = MkFoo undefined :: Foo Succ';
*>* f3 = MkFoo undefined :: Foo Succ'';
*>* f4 = MkFoo undefined :: Foo (Add (Succ Zero));
*
yeah, why not! Have them all be the same thing.
(i added the missing "Foo" on f4)
add Zero b = b
add (Succ a) b = Succ (add a b)
mult Zero b = Zero
mult (Succ a) b = add b (mult a b)
fact Zero = Zero
fact (Succ n) = mult (Succ n) (fact n)
data Foo f = MkFoo (f ())
succ' = Succ
succ'' n = Succ n
-- which of these types are the same?
f1 = MkFoo undefined :: Foo Succ
f2 = MkFoo undefined :: Foo succ'
f3 = MkFoo undefined :: Foo succ''
f4 = MkFoo undefined :: Foo (add (Succ Zero))
add to haskell
- eta-expanding of (add (Succ Zero)) in (\x -> add (Succ Zero) x)
- compile-time evaluation of type expressions (handling unbounded parameters
like "x" above)
and that should do it!
I don't think this is a crazy as it sounds. Cayenne has already started
computing types at compile-time.
I'm currently working on merd (http://merd.net) which has a such a type system.
eg:
range(n, m) =
if n < m then
n | range(n + 1, m)
else
n
Two_to_height = range(2, 8) #=> 2|3|4|5|6|7|8
restricted_identity !! Two_to_height -> Two_to_height
restricted_identity(x) = x
restricted_identity(4) #=> 4
restricted_identity(1) #=> compile-time error: 1 is not in 2|3|4|5|6|7|8