[Haskell-cafe] Shouldnt this be lazy too?
andrewcoppin at btinternet.com
Mon Sep 24 17:28:25 EDT 2007
Neil Mitchell wrote:
>>> Pretty much, yes.
>> So I just need to write
>> newtype LazyNatural = LazyNatural [()]
> data Nat = Zero | Succ Nat
> it's your choice really.
I'm guessing there's going to be fairly minimal performance difference.
(Or maybe there is. My way uses a few additional pointers. But it also
allows me to elegantly recycle existing Prelude list functions, so...)
>> and then add some suitable instances. ;-)
> Yes. Lots of them. Lots of instances and lots of methods.
>> Hey, the "length" function would then just be
>> ln_length :: [x] -> LazyNatural
>> ln_length = LazyNatural . map (const ())
>> Ooo, that's hard.
> Nope, its really easy. Its just quite a bit of work filling in all the
> instances. I bet you can't do it and upload the results to hackage
> within 24 hours :-)
*ALL* the instances? No.
A small handful of them? Sure. How about this...
module LazyNatural (LazyNatural ()) where
newtype LazyNatural = LN [()]
instance Show LazyNatural where
show (LN x) = "LN " ++ show (length x)
instance Eq LazyNatural where
(LN x) == (LN y) = x == y
instance Ord LazyNatural where
compare (LN x) (LN y) = raw_compare x y
raw_compare () (_:_) = LT
raw_compare () () = EQ
raw_compare (_:_) () = GT
raw_compare (_:x) (_:y) = raw_compare x y
instance Num LazyNatural where
(LN x) + (LN y) = LN (x ++ y)
(LN x) - (LN y) = LN (raw_minus x y)
(LN x) * (LN y) = LN (concatMap (const x) y)
negate _ = error "negate is not defined for LazyNatural"
abs = id
signum (LN ) = LN 
signum (LN _) = LN [()]
fromInteger = LN . flip genericReplicate ()
raw_minus (_:a) (_:b) = raw_minus a b
raw_minus (a) () = a
raw_minus _ _ = error "negative result from subtraction"
More information about the Haskell-Cafe