我原以为以下代码会运行并立即退出,因为p
实际上从未被使用,但是它运行了7分钟以上,然后似乎被操作系统杀死了。
{-# 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
我以为这与绑定运算符有关,但以下代码需要运行9秒钟:
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]
而这段代码会立即退出:
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]
>>=
是严格的,那么我问题中的第三个代码块不应该和第二个一样慢吗? - bwrogaproduct'
需要很长时间才能到达WNHF。你在第二个片段上遇到的挂起是因为之后发生的乘法需要很长时间才能显示数字。我的例子向你展示了你的片段不同的原因并不是>>=
右侧的Nothing
或Just
。 - Alec