Philip Armstrong wrote:
> genericLength           :: (Num i) => [b] -> i
> genericLength []        =  0
> genericLength (_:l)     =  1 + genericLength l
> 
> So genericLength is lazily building up unevaluated (+) expressions and
> running out of stack space.
> 
> Is there a good reason for genericLength to be lazy?

Yes, since addition in  i  may well be lazy.

  data Nat = Zero | Succ Nat

  instance Num Nat where
     Zero     + b = b
     (Succ a) + b = Succ (a + b)
     ...

  natLength :: [a] -> Nat
  natLength = genericLength

Also, you can turn the foldr into a foldl' with a cleverly chosen data
type like

  data Int' = I Int | Plus Int' Int'

  eval :: Int' -> Int
  eval = eval' 0
     where
     eval' (I i) k      = k + i
     eval' (Plus x y) k = eval' y $! eval' x k

  instance Num Int' where
     (+) = Plus
     ...

or in its bare essence

  newtype DiffInt = DI { unDI :: Int -> Int }

  instance Num DiffInt where
     (+) f g k = DI $ unDI g $! unDI f k

  evalDI :: DiffInt -> Int
  evalDI f = unDI f 0


Regards,
apfelmus

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to