{-# LANGUAGE BangPatterns #-} import Control.DeepSeq data Tuple a b = Tuple !a !b deriving (Show, Read, Eq, Ord) lazy, strict :: a -> () lazy _ = () strict !_ = () -- | strict in parameter, thanks to pattern match to 0 -- but lazy in evaluation of result fact :: Integer -> Integer fact 0 = 1 fact x = x * fact (x - 1) -- | tail-recursive strict factorial fact' :: Integer -> Integer fact' x = afact 1 x where afact !accum 0 = accum afact !accum x = afact (accum * x) (x - 1) nested :: (a, [b]) -> () nested (_ , []) = () nested (!x, (_:(!xs))) = () -- | List with strict structure but lazy values data SList a = SNil | SCons a !(SList a) deriving (Eq, Ord, Show, Read) toSList :: [a] -> SList a toSList = foldr SCons SNil fromSList :: SList a -> [a] fromSList SNil = [] fromSList (SCons x xs) = x : fromSList xs instance NFData a => NFData (SList a) where rnf SNil = () rnf (SCons x xs) = rnf x `seq` rnf xs slTake :: Int -> SList a -> SList a slTake _ SNil = SNil slTake !n (SCons x xs) | n <= 0 = SNil | otherwise = SCons x (slTake (n - 1) xs) slLast :: SList a -> a slLast (SCons x SNil) = x slLast (SCons _ xs) = slLast xs slRepeat :: a -> SList a slRepeat x = SCons x (slRepeat x) facts, facts' :: SList Integer facts = toSList $ map fact [1..100000] facts' = toSList $ map fact' [1..100000] facts'' = force facts' -- force x = x `deepseq` x