【发布时间】:2016-09-13 00:35:14
【问题描述】:
1 背景
考虑 Haskell 的以下 sn-p:
data T = T { f1 :: String
, f2 :: T
} deriving (Eq, Show)
r1 = T { f1 = "val1"
, f2 = r2
} :: T
r2 = T { f1 = "val2"
, f2 = r1
} :: T
注意r1 是如何相对于r2 相互递归的。 AFAIK,这在 Haskell 中完全没问题(只要你不使用这两个值导致相互递归的调用循环永远不会终止)。例如,r2 的用户可能希望通过f1 (f2 r2)(在本例中为“val1”)访问值f1 r1。 (事实上,这就是我尝试在自己的代码中使用这些类型的数据结构的方式。)
2 问题
现在考虑以下 HSpec 单元测试:
describe "A mutually recursive value should be equal to itself" $ do
r1 `shouldBe` r1
这会导致测试编译器停止一段时间,然后最终失败。这是否意味着我的代码有问题,或者这只是 shouldBe 方式的怪癖已定义(我假设它检查相等性的方式不是懒惰的,并且涉及相互递归的非终止调用)?如果这只是 HSpec 的 shouldBe 函数的一个怪癖,那么有没有办法检查相互递归值之间的相等性?我最终希望能够做的事情如下:
r3 = T { f1 = "val1"
, f2 = r2
} :: T
describe "A mutually recursive value should be equal to itself" $ do
r1 `shouldBe` r3
【问题讨论】:
-
问题是你的
Eq实例(懒惰无关紧要 -shouldBe当然会迫使他们得到Bool结果)(和Show也一样)那些会循环永远 - 所以你应该自己实现这些 - 使用某种形式的 loop - 检测或根本不使用递归值
标签: haskell mutual-recursion hspec