dme*_*sky 6 testing debugging haskell applicative monoids
假设我有一个功能(它没有任何实际应用,只是学术兴趣,因此编写它的奇怪方式,使用monoids,applicative functors和fixpoint combinators)
f :: Num a => a -> Sum a
f = fix ((<>) <$> Sum <*>)
Run Code Online (Sandbox Code Playgroud)
它可能会出现问题,但我无法确定它是否会在我测试之前完成预期的操作.
如何进行测试和/或调试呢?我的意思是像在可能的情况下在几次迭代之后看到结果take 10 [1..].
我了解一些简单的调试工具ghci一样:break和:step,但步入非终止计算,所以我不能检查任何东西(它甚至有问题的^C话).我想不出如何使用trace从Debug模块中的这一功能无论是.
任何指针将不胜感激.
Art*_*yom 10
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, _"
Run Code Online (Sandbox Code Playgroud)
但是,这里我们不能直接使用它:Integers的求和是严格的,不像(:)用于构建列表.因此应该使用另一种类型.
首先,一些导入(我们还需要能够派生Data,因此approxShow可以用来显示我们的自定义类型):
{-# LANGUAGE DeriveDataTypeable #-}
import Data.Data
import Data.Monoid
import Data.Function
import Control.Applicative
import Test.ChasingBottoms.ApproxShow
Run Code Online (Sandbox Code Playgroud)
类型本身(非常基本)及其Num实例:
data S = N Integer | S :+ S
deriving (Typeable, Data)
instance Num S where
(+) = (:+)
fromInteger = N
--other operations do not need to be implemented
Run Code Online (Sandbox Code Playgroud)
最后,功能:
f :: S -> Sum S
f = fix ((<>) <$> Sum <*>)
Run Code Online (Sandbox Code Playgroud)
以下是我们如何看待f正在做什么,例如,1等常见数字:
*Main> approxShow 5 (getSum (f 1))
"(N 1) :+ ((N 1) :+ ((N 1) :+ ((N _) :+ (_ :+ _))))"
Run Code Online (Sandbox Code Playgroud)
当然,观看演变可能更有趣:
*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 _) :+ (_ :+ _))))))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
265 次 |
| 最近记录: |