包ChasingBottoms
其approxShow
可以幫助你探索部分的評估值:
$ cabal install ChasingBottoms
$ ghci
> import Test.ChasingBottoms.ApproxShow
> import Data.Function
> approxShow 10 (fix (1:))
"[1, 1, 1, 1, 1, 1, 1, 1, 1, _"
不過,在這裏我們不能直接使用它:求和Integer
s是嚴格,不像(:)
這是用來建立一個清單。因此應該使用另一種類型。
首先,一些進口(我們還需要能夠獲得Data
,使approxShow
可以用來展示我們的定製型):
{-# LANGUAGE DeriveDataTypeable #-}
import Data.Data
import Data.Monoid
import Data.Function
import Control.Applicative
import Test.ChasingBottoms.ApproxShow
類型本身(非常基本的),其Num
例如:
data S = N Integer | S :+ S
deriving (Typeable, Data)
instance Num S where
(+) = (:+)
fromInteger = N
--other operations do not need to be implemented
最後,函數:
f :: S -> Sum S
f = fix ((<>) <$> Sum <*>)
這裏是我們怎麼能看到什麼f
用,比如說做,一個共同的數字,例如1:
*Main> approxShow 5 (getSum (f 1))
"(N 1) :+ ((N 1) :+ ((N 1) :+ ((N _) :+ (_ :+ _))))"
當然,它可能是更值得關注的演變:
*Main> Control.Monad.forM_ [0..7] $ \i -> putStrLn $ approxShow i (getSum (f 1))
_
_ :+ _
(N _) :+ (_ :+ _)
(N 1) :+ ((N _) :+ (_ :+ _))
(N 1) :+ ((N 1) :+ ((N _) :+ (_ :+ _)))
(N 1) :+ ((N 1) :+ ((N 1) :+ ((N _) :+ (_ :+ _))))
(N 1) :+ ((N 1) :+ ((N 1) :+ ((N 1) :+ ((N _) :+ (_ :+ _)))))
(N 1) :+ ((N 1) :+ ((N 1) :+ ((N 1) :+ ((N 1) :+ ((N _) :+ (_ :+ _))))))
那麼,如果你擴展到'f = fix(\ g - > \ x - > Sum x <> gx)' – phg 2013-04-05 12:31:13