- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试一个简单的玫瑰树代码。
data RoseT a = Leaf a | Node a [RoseT a] deriving (Show)
instance Eq (RoseT a) where
(==) (Leaf a) (Leaf b) = a == b
(==) (Node a rs1) (Node b rs2) = and ((a==b): (zipWith (==) rs1 rs2))
(==) _ _ = False
我可以使用quickcheck来测试Eq实例的实现吗?如果是,怎么办?如果不是,最好的选择是什么?
我还有一个执行以下操作的函数:
appendPath :: (RoseT a) -> (RoseT (a,[a]))
appendPath rst = appendPath' [] rst
appendPath :: [a] -> (RoseT a) -> (RoseT (a,[a]))
appendPath' p (Leaf a) = Leaf (a,p)
appendPath' p (Node a rs) = Node (a,p) (map (appendPath' (a:p)) rs)
函数appendPath将一棵玫瑰树作为输入,并返回一棵玫瑰树,该树的每个节点都有从节点到根的路径。我在另一个函数中使用了此信息。
如何使用 Quickcheck 在大型玫瑰树上检查此实现?
编辑:正如 mhwombat 所建议的,编写将类型参数作为参数的生成器似乎是不可能的。这是我的类型参数。我想构造一个代表有效随机算术表达式的字符串 RoseT
,其中算术表达式本身遵循以下结构:
数据表达式 = Var String |添加表达式 [表达式] | MulExpr [Expr] 导出 Show
那么,有没有一种方法可以生成随机 RoseT Expr
,其中 Expr 本身是仅使用快速检查随机生成的?
再次感谢 mhwombat,谢谢你对我婴儿步的包容。
最佳答案
除非我遗漏了某些内容,否则您的 RoseT
的 Eq
实现与默认的派生实现相同。所以你可以说
data RoseT a = Leaf a | Node a [RoseT a] deriving (Show, Eq)
并且忘记实例Eq(RoseT a)在哪里
东西。
下一个问题是这是否能满足您的测试需求。如果您使用浮点类型参数(例如 RoseT Double
)进行测试,则需要考虑由于舍入而产生的差异。在这种情况下,您需要的是一个比较两棵树并查看值是否“足够接近”的函数。
但是,我怀疑您的 RoseT
实现不会以任何方式依赖于类型参数。在这种情况下,您可以使用 Char
或 Int
等简单类型来测试它,并使用 ==
进行您需要的任何比较。
您有两个 appendPath
类型签名。我认为第二个应该是 appendPath'
:
appendPath' :: [a] -> (RoseT a) -> (RoseT (a,[a]))
现在介绍如何测试它。如果您/QuickCheck 对正在测试的树的复杂性有一定的控制,那就最好了。这会对您有所帮助,因为最简单的树将首先进行测试,因此您可以“尽早”发现错误(即使用更容易调试的更简单的测试用例)。您可以通过为您的类实现一个“大小”的生成器来做到这一点。这是一种方法。 “size”参数的值越高,树可能具有的级别就越多。
type TestRoseT = RoseT Char
sizedArbTestRoseT :: Int -> Gen TestRoseT
sizedArbTestRoseT 0 = do
c <- arbitrary
return $ Leaf c
sizedArbTestRoseT n = do
c <- arbitrary
subtreeCount <- choose (0,n-1)
subtrees <- vectorOf subtreeCount (sizedArbTestRoseT (n-1))
return $ Node c subtrees
instance Arbitrary TestRoseT where
arbitrary = sized sizedArbTestRoseT
prop_appendPath_does_something :: TestRoseT -> Property
prop_appendPath_does_something t = undefined -- stub
我们可以对生成的测试数据进行采样,如下所示:
λ> sample (sizedArbTestRoseT 2)
Node '\a' [Node '\RS' []]
Node '?' []
Node '\158' []
Node 'o' [Node 'E' []]
Node '\196' []
Node '4' [Node 'G' []]
Node ';' [Node 'f' []]
Node 'A' [Node '\CAN' []]
Node '!' []
Node 'q' [Node '\t' []]
Node '\'' [Node '\212' []]
对于您的 Expr
类型,我们可以编写一个生成器,如下所示:
sizedArbExpr :: Int -> Gen Expr
sizedArbExpr 0 = do
s <- arbitrary
return $ Var s
sizedArbExpr n = do
es <- vectorOf 2 (sizedArbExpr (n-1))
elements [AddExpr es, MulExpr es]
instance Arbitrary Expr where
arbitrary = sized sizedArbExpr
我们需要修改 TestRoseT
及其生成器,以便树的复杂性与“size”参数一致:
type TestRoseT = RoseT Expr
sizedArbTestRoseT :: Int -> Gen TestRoseT
sizedArbTestRoseT 0 = do
c <- sizedArbExpr 0 -- changed this to keep complexity in bounds
return $ Leaf c
sizedArbTestRoseT n = do
c <- sizedArbExpr (n-1) -- changed this to keep complexity in bounds
subtreeCount <- choose (0,n-1)
subtrees <- vectorOf subtreeCount (sizedArbTestRoseT (n-1))
return $ Node c subtrees
测试这些修改会得到如下结果:
λ> sample (sizedArbTestRoseT 3)
Node (MulExpr [MulExpr [Var "",Var ""],AddExpr [Var "",Var ""]]) [Node (MulExpr [Var "",Var ""]) [Node (Var "") []]]
Node (MulExpr [AddExpr [Var "",Var ""],AddExpr [Var "",Var ""]]) [Node (AddExpr [Var "",Var ""]) []]
Node (MulExpr [AddExpr [Var "\164D",Var "\151\246\FS"],MulExpr [Var ":\149j\EM",Var "h\253\255"]]) [Node (MulExpr [Var "\CAN\a\ACK",Var "\184"]) [Node (Var "t\154]\\") []],Node (MulExpr [Var "\135",Var "\f\DEL\\"]) [Node (Var "\SOH\DEL") []]]
Node (AddExpr [AddExpr [Var "",Var ""],MulExpr [Var "Kj\STXV",Var "D\141<s\187"]]) []
Node (AddExpr [MulExpr [Var "\252",Var "`"],MulExpr [Var "\167`t\196",Var ":\135\NULdr\237\167"]]) []
Node (AddExpr [MulExpr [Var "]\173\&28D\SOCom",Var "^\196\ETB2\216\&2\GS\ENQ\ENQ"],AddExpr [Var "$bB\212\SOH\146\234",Var "\DC3\213\&3\SUB\\}^\246(\200"]]) [Node (MulExpr [Var "l;\133\EM\147#\SUBN\\\t",Var "\235\151U\129m3|"]) [Node (Var "\NULb\133") []],Node (AddExpr [Var "\187\EOT\165S\207\r\"\RS",Var "4"]) []]
Node (MulExpr [MulExpr [Var "%0eK",Var "`N**k\FS6\NAK"],MulExpr [Var "'lUL\NAKRPc\ENQR",Var "j\232+`\FS@n"]]) [Node (AddExpr [Var "H\DC1C%\DC48<\t\ETX.L",Var "\235+\v\STXX,\NAK\SUBQc="]) [Node (Var "f\254oX?w\224\195~/") []]]
Node (AddExpr [AddExpr [Var "P",Var "\148G\STX\DEL*\136(\161\159\&7"],AddExpr [Var "\218\136-",Var "9?\128\159\b\b%3t}\131qe"]]) [Node (MulExpr [Var "\198\249\&4\176\193/}\DC28",Var ")Gl0ym\GS"]) [Node (Var ")\204\226qA\175") []]]
Node (MulExpr [MulExpr [Var "\t\186r.",Var "j\ENQ\183\NUL\NAK\129:rg[\170o\157g\238"],AddExpr [Var "\218F\226\248\156\225\&1",Var "vu\SOH\138+CKW\EM\167\&1n"]]) [Node (MulExpr [Var ",\241\158={o\182\"5\t\STX\ETX\DC2\218\162",Var "\197\&1"]) [Node (Var "u?a};\238") []]]
Node (MulExpr [MulExpr [Var "*",Var "R"],AddExpr [Var "\CAN8C",Var "\232V.\172ILy\162a"]]) []
Node (MulExpr [MulExpr [Var "\SI\240NF\249-\v$",Var "K`\STX\231w{"],MulExpr [Var "\DC1\255\209",Var "/\227\146\236\STX\185T3r\f"]]) [Node (MulExpr [Var "\229,\DLE\NAKwf[7P\160\DEL",Var "\134#\RS\SI0KCg\195\NAK\"\191\&6\243\193\SI"]) [Node (Var "\226\&7b8\f\EOTgF\171\GS}\189c\SUBc\ETX") []]]
顺便说一句,你说“似乎不可能编写以类型参数作为参数的生成器”。实际上可以这样做,但我认为这并不是您真正想要的。
顺便说一句,您想要创建一棵树 (RoseT
),其中叶子包含二叉树 (Expr
),这似乎有点不寻常。换句话说,你正在创造树中的树。当然,我不知道你的应用程序。
关于Haskell 快速检查生成和测试玫瑰树?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17615138/
关于 B 树与 B+ 树,网上有一个比较经典的问题:为什么 MongoDb 使用 B 树,而 MySQL 索引使用 B+ 树? 但实际上 MongoDb 真的用的是 B 树吗?
如何将 R* Tree 实现为持久(基于磁盘)树?保存 R* 树索引或保存叶值的文件的体系结构是什么? 注意:此外,如何在这种持久性 R* 树中执行插入、更新和删除操作? 注意事项二:我已经实现了一个
目前,我正在努力用 Java 表示我用 SML 编写的 AST 树,这样我就可以随时用 Java 遍历它。 我想知道是否应该在 Java 中创建一个 Node 类,其中包含我想要表示的数据,以及一个数
我之前用过这个库http://www.cs.umd.edu/~mount/ANN/ .但是,它们不提供范围查询实现。我猜是否有一个 C++ 范围查询实现(圆形或矩形),用于查询二维数据。 谢谢。 最佳
在进一步分析为什么MySQL数据库索引选择使用B+树之前,我相信很多小伙伴对数据结构中的树还是有些许模糊的,因此我们由浅入深一步步探讨树的演进过程,在一步步引出B树以及为什么MySQL数据库索引选择
操作系统的那棵“树” 今天从一颗 开始,我们看看如何从小树苗长成一颗苍天大树。 运转CPU CPU运转起来很简单,就是不断的从内存取值执行。 CPU没有好好运转 IO是个耗费时间的活,如果CPU在取值
我想为海洋生物学类(class)制作一个简单的系统发育树作为教育示例。我有一个具有分类等级的物种列表: Group <- c("Benthos","Benthos","Benthos","Be
我从这段代码中删除节点时遇到问题,如果我插入数字 12 并尝试删除它,它不会删除它,我尝试调试,似乎当它尝试删除时,它出错了树的。但是,如果我尝试删除它已经插入主节点的节点,它将删除它,或者我插入数字
B+ 树的叶节点链接在一起。将 B+ 树的指针结构视为有向图,它不是循环的。但是忽略指针的方向并将其视为链接在一起的无向叶节点会在图中创建循环。 在 Haskell 中,如何将叶子构造为父内部节点的子
我在 GWT 中使用树控件。我有一个自定义小部件,我将其添加为 TreeItem: Tree testTree = new Tree(); testTree.addItem(myWidget); 我想
它有点像混合树/链表结构。这是我定义结构的方式 struct node { nodeP sibling; nodeP child; nodeP parent; char
我编写了使用队列遍历树的代码,但是下面的出队函数生成错误,head = p->next 是否有问题?我不明白为什么这部分是错误的。 void Levelorder(void) { node *tmp,
例如,我想解析以下数组: var array1 = ["a.b.c.d", "a.e.f.g", "a.h", "a.i.j", "a.b.k"] 进入: var json1 = { "nod
问题 -> 给定一棵二叉树和一个和,确定该树是否具有从根到叶的路径,使得沿路径的所有值相加等于给定的和。 我的解决方案 -> public class Solution { public bo
我有一个创建 java 树的任务,它包含三列:运动名称、运动类别中的运动计数和上次更新。类似的东西显示在下面的图像上: 如您所见,有 4 种运动:水上运动、球类运动、跳伞运动和舞蹈运动。当我展开 sk
我想在 H2 数据库中实现 B+ Tree,但我想知道,B+ Tree 功能在 H2 数据库中可用吗? 最佳答案 H2 已经使用了 B+ 树(PageBtree 类)。 关于mysql - H2数据库
假设我们有 5 个字符串数组: String[] array1 = {"hello", "i", "cat"}; String[] array2 = {"hello", "i", "am"}; Str
我正在处理树。每个节点都有带有 Tree * 值的对象。我读取的数据如下所示: 1 2 2 ... 这意味着,将 1 作为 0 的子节点,将 2 作为 1 的子节点,将 3 作为 o 2 的子节点。在
我正在寻找一个好的 JavaScript 树/树网格包。现在——在你回答之前: 它需要能够在大量节点上正常运行。可能有 1,000 个兄弟节点。它需要能够在 2 或 3 秒内绘制到 1,000 个节点
下面的代码块究竟是如何工作的?更具体地说,程序如何知道返回哪个选项? return ancestor (node1->left(), node2) || ancestor
我是一名优秀的程序员,十分优秀!