I expected that the following code would run and exit immediately because p
is never actually used, but instead, it runs for over 7 minutes and then is seemingly killed by the os.
{-# LANGUAGE DeriveFunctor #-}
import Control.Monad (liftM2)
main = print $ ((product' 1 >>= \p -> Nothing) :: Maybe Integer)
data Term f = In { out :: f (Term f) }
type Algebra f a = (f a -> a)
cata :: (Functor f) => Algebra f a -> Term f -> a
cata g t = g $ fmap (cata g) $ out t
type CoAlgebra f a = (a -> f a)
ana :: (Functor f) => CoAlgebra f a -> a -> Term f
ana g a = In $ fmap (ana g) $ g a
data A a = A (Maybe Integer) [a] | B deriving (Functor)
product' :: Integer -> Maybe Integer
product' i = cata h $ ana g $ fmap Just [i..1000]
where g (x:xs) = A x $ replicate 10 xs
g [] = B
h (A k l) = foldr (liftM2 (*)) k l
h B = Just 1
I thought this had to do with the bind operator, but the following code takes 9 seconds to run:
import Control.Monad (liftM2)
import Data.Foldable (foldr1)
main = print $ ((p >>= \p' -> Just p') :: Maybe Integer)
p :: Maybe Integer
p = foldr1 (liftM2 (*)) $ fmap Just [1..100000]
And this code exits immediately:
import Control.Monad (liftM2)
import Data.Foldable (foldr1)
main = print $ ((p >>= \p' -> Nothing) :: Maybe Integer)
p :: Maybe Integer
p = foldr1 (liftM2 (*)) $ fmap Just [1..100000]