使用 Arbitrary 类型类生成随机二叉搜索树
Generating random binary search trees with the Arbitrary typeclass
我正在处理一个问题集,我必须为二叉搜索树编写一个任意实例。这是我到目前为止编写的代码:
data Tree e = E | N (Tree e) e (Tree e)
insert :: (Ord e) => e -> Tree e -> Tree e
-- assume this is implemented, so I can use it below
instance (Ord a, Arbitrary a) => Arbitrary (Tree a) where
arbitrary :: Gen (Tree a)
arbitrary = sized gen
where
gen :: Int -> Gen a
gen n =
frequency
[
(1, return E),
-- vvvvvvvvv problematic vvvvvvvvvv
(n, return $ insert (4::Int) (gen (n `div` 2)))
]
我不确定如何让频率列表的第二行进行类型检查。我可以看到 gen
returns a Gen Tree
and insert
requires a Tree
for its second argument,但我不确定如何用它重构代码知识。但是,我需要使用 insert
函数。另一个问题是我需要获取随机元素值,但我暂时把它放在一边,让每个新元素成为 4 :: Int
.
gen (n `div` 2)
的类型是 Gen (Tree a)
,所以你应该 fmap
那棵树,所以:
instance (Ord a, Arbitrary a) => Arbitrary (Tree a) where
arbitrary = sized gen
where gen n = frequency [
(1, return E)
, (n, <strong>insert <$> arbitrary <*> gen (n `div` 2)</strong>)
]
这将因此生成一个 arbitrary
值,然后是大小为 n `div` 2
的任意 Tree
,然后 return insert
的结果该任意子树的任意值。
我正在处理一个问题集,我必须为二叉搜索树编写一个任意实例。这是我到目前为止编写的代码:
data Tree e = E | N (Tree e) e (Tree e)
insert :: (Ord e) => e -> Tree e -> Tree e
-- assume this is implemented, so I can use it below
instance (Ord a, Arbitrary a) => Arbitrary (Tree a) where
arbitrary :: Gen (Tree a)
arbitrary = sized gen
where
gen :: Int -> Gen a
gen n =
frequency
[
(1, return E),
-- vvvvvvvvv problematic vvvvvvvvvv
(n, return $ insert (4::Int) (gen (n `div` 2)))
]
我不确定如何让频率列表的第二行进行类型检查。我可以看到 gen
returns a Gen Tree
and insert
requires a Tree
for its second argument,但我不确定如何用它重构代码知识。但是,我需要使用 insert
函数。另一个问题是我需要获取随机元素值,但我暂时把它放在一边,让每个新元素成为 4 :: Int
.
gen (n `div` 2)
的类型是 Gen (Tree a)
,所以你应该 fmap
那棵树,所以:
instance (Ord a, Arbitrary a) => Arbitrary (Tree a) where
arbitrary = sized gen
where gen n = frequency [
(1, return E)
, (n, <strong>insert <$> arbitrary <*> gen (n `div` 2)</strong>)
]
这将因此生成一个 arbitrary
值,然后是大小为 n `div` 2
的任意 Tree
,然后 return insert
的结果该任意子树的任意值。