tl; dr:Arbitrary如果你的数据类型允许过多的嵌套,你如何编写不爆炸的实例?您如何保证这些实例能够生成真正随机的数据结构样本?
我想生成随机树结构,然后在用我的库代码修改它们之后测试这些结构的某些属性.(注意:我正在编写子类型算法的实现,即给定类型的层次结构,类型A是类型B的子类型.通过在层次结构中包含多继承和后初始化更新,可以使其任意复杂化不支持这些的经典方法是Schubert编号,我所知道的最新结果是Alavi et al.2008.)
我们来看玫瑰树的例子如下Data.Tree:
data Tree a = Node a (Forest a)
type Forest a = [Tree a]
Run Code Online (Sandbox Code Playgroud)
Arbitray的一个非常简单的(并且不用尝试在家)实例将是:
instance (Arbitrary a) => Arbitrary (Tree a) where
arbitrary = Node <$> arbitrary <$> arbitrary
Run Code Online (Sandbox Code Playgroud)
由于a已经有一个Arbitrary类型约束的实例,并且Forest将有一个,因为[]也是一个实例,这似乎是直截了当的.它不会(通常)以非常明显的原因终止:因为它生成的列表是任意长的,结构变得太大,并且它们很可能不适合内存.即使是更保守的方法:
arbitrary = Node <$> arbitrary <*> oneof [arbitrary,return []]
Run Code Online (Sandbox Code Playgroud)
因为同样的原因,再也不会工作了.人们可以调整大小参数,以保持列表的长度,但即使这样也不能保证终止,因为它仍然是多个连续的掷骰子,并且它可能会非常糟糕(我希望奇数节点有100个)孩子们.)
这意味着我需要限制整个树的大小.那不是那么直截了当.unordered-containers很简单:只需使用fromList.这在这里不是那么容易:你如何随机地将一个列表变成一棵树,而不会产生任何一种或另一种偏见(即不利于左分支,或者是非常左倾的树.)
列表中的某种广度优先构造(Data.Tree所有预先提供的功能)都很棒,我想我可以写一个,但结果却是非平凡的.由于我现在正在使用树,但是后来会使用更复杂的东西,我想我可能会尝试找到更通用,更简单的解决方案.有没有,还是我不得不求助于编写我自己的非平凡Arbitrary发电机?在后一种情况下,我实际上可能只是采用单元测试,因为这似乎太多了.
我想生成一个看起来像这样的图形:

我的原始数据集看起来像这样:
> bb[sample(nrow(bb), 20), ]
IMG QUANT FIX
25663 1 1 0
7936 2 2 0
23586 3 2 0
23017 2 2 1
31363 1 3 1
7886 2 2 0
23819 3 3 1
29838 2 2 1
8169 2 3 1
9870 2 3 0
31440 2 1 0
35564 3 1 0
24066 1 2 0
12020 3 2 0
6742 3 2 0
6189 2 3 0
26692 2 3 0
1387 3 2 …Run Code Online (Sandbox Code Playgroud) 使用GHC.TypeLits,我们可以编写一个简单的类型级编号列表(或矢量).
> {-# LANGUAGE TypeOperators, KindSignatures, GADTs, DataKinds, ScopedTypeVariables #-}
> import GHC.TypeLits
> data Vec :: * -> Nat -> * where
> VNil :: Vec e 0
> (:-) :: e -> Vec e n -> Vec e (n+1)
Run Code Online (Sandbox Code Playgroud)
这是规范的矢量定义TypeLits.直观地说,追加操作应如下所示:
> vecAppend :: Vec e n -> Vec e m -> Vec e (n + m)
> vecAppend VNil vec = vec
> vecAppend (a :- as) vec = a :- vecAppend as vec …Run Code Online (Sandbox Code Playgroud) 首先,我要完成的任务的简化版本:我有几个大文件(相当于30GB),我想修剪重复的条目.为此,我建立了一个数据散列数据库,逐个打开文件,散列每个项目,并将其记录在数据库和输出文件中,如果它的散列不在数据库中.
我知道如何使用迭代器,枚举器,我想尝试管道.我也知道如何用管道来做,但现在我想使用管道和持久性.我遇到了类型问题,可能还有整个概念ResourceT.
这里有一些伪代码来说明问题:
withSqlConn "foo.db" $ runSqlConn $ runResourceT $
sourceFile "in" $= parseBytes $= dbAction $= serialize $$ sinkFile "out"
Run Code Online (Sandbox Code Playgroud)
问题在于dbAction功能.我想自然地在这里访问数据库.由于它所做的动作基本上只是一个过滤器,我首先想到这样写:
dbAction = CL.mapMaybeM p
where p :: (MonadIO m, MonadBaseControl IO (SqlPersist m)) => DataType -> m (Maybe DataType)
p = lift $ putStrLn "foo" -- fine
insert $ undefined -- type error!
return undefined
Run Code Online (Sandbox Code Playgroud)
我得到的具体错误是:
Could not deduce (m ~ b0 m0)
from the context (MonadIO m, MonadBaseControl IO (SqlPersist m))
bound by …Run Code Online (Sandbox Code Playgroud) (注意:这篇文章是一个literate-haskell文件.你可以将它复制粘贴到文本缓冲区中,保存为someFile.lhs,然后使用ghc运行它.)
问题描述:我想要创建一个具有两个不同节点类型的图形,这些节点类型相互引用.以下示例非常简化.这两个数据类型
A和B,实际上是相同的位置,但有一个原因,他们在原来的程序不同.
我们会把枯燥的东西拿走.
> {-# LANGUAGE RecursiveDo, UnicodeSyntax #-}
>
> import qualified Data.HashMap.Lazy as M
> import Data.HashMap.Lazy (HashMap)
> import Control.Applicative ((<*>),(<$>),pure)
> import Data.Maybe (fromJust,catMaybes)
Run Code Online (Sandbox Code Playgroud)
数据类型定义本身是微不足道的:
> data A = A String B
> data B = B String A
Run Code Online (Sandbox Code Playgroud)
为了象征两者之间的差异,我们将给它们一个不同的
Show实例.
> instance Show A where
> show (A a (B b _)) = a ++ ":" ++ b
>
> instance Show B where
> show …Run Code Online (Sandbox Code Playgroud) 我正在尝试与Haskell的XML工具箱(HXT)达成协议,我正在某个地方撞墙,因为我似乎并不完全掌握箭头作为计算工具.
这是我的问题,我希望使用GHCi会话更好地说明:
> let parse p = runLA (xread >>> p) "<root><a>foo</a><b>bar</b><c>baz</c></root>"
> :t parse
parse :: LA XmlTree b -> [b]
Run Code Online (Sandbox Code Playgroud)
所以Parse是一个小帮助函数,它将我给它的任何箭头应用于普通的XML文档
<root>
<a>foo</a>
<b>bar</b>
<c>baz</c>
</root>
Run Code Online (Sandbox Code Playgroud)
我定义了另一个辅助函数,这次是在具有给定名称的节点下提取文本:
> let extract s = getChildren >>> isElem >>> hasName s >>> getChildren >>> getText
> :t extract
extract :: (ArrowXml cat) =>
String -> cat (Data.Tree.NTree.TypeDefs.NTree XNode) String
> parse (extract "a" &&& extract "b") -- extract two nodes' content.
[("foo","bar")]
Run Code Online (Sandbox Code Playgroud)
在这个函数的帮助下,很容易使用&&&组合子来配对两个不同节点的文本,然后将它传递给构造函数,如下所示:
> parse (extract "a" …Run Code Online (Sandbox Code Playgroud) 我有一个Date对象列表和一个目标Date.我想在列表中找到最接近目标日期的日期,但只查找目标日期之前的日期.
示例:2008-10-1 2008-10-2 2008-10-4
目标日期为2008-10-3,我希望得到2008-10-2
最好的方法是什么?
这是一个非常简单的请求,我无法相信我还没有找到解决方案,但我一直在寻找它,没有运气.
我.Rnw在Emacs中加载了一个文件,我M-n s用来编译它.一切都运作良好,甚至打开一个R缓冲区.大.但是那个缓冲区完全没用:它不包含我刚刚提供的对象!
示例最小.Rnw文件:
\documentclass{article}
\begin{document}
<<>>=
foo <- "bar"
@
\end{document}
Run Code Online (Sandbox Code Playgroud)
使用M-n s,我现在有一个新的R缓冲区,会话已加载,但是:
> foo
Error: object 'foo' not found
Run Code Online (Sandbox Code Playgroud)
这令人失望.我想以交互方式使用数据.我如何实现这一目标?我不希望C-c C-c每次更改代码时逐行或逐个区域地获取文件.理想情况下,它应该像RStudio的源函数一样,让我有一个完全准备好的R会话.
我还没有用sweave试过这个,只有knitr.
编辑:eval=TRUE块选项似乎不会导致正确的行为.
给定一个任意树,我可以使用舒伯特编号在该树上构建一个子类型关系:
constructH :: Tree a -> Tree (Type a)
Run Code Online (Sandbox Code Playgroud)
其中Type嵌套原来的标签,并且还提供了执行父/子(或子类型)的检查所需要的数据.使用Schubert编号,两个Int参数就足够了.
data Type a where !Int -> !Int -> a -> Type a
Run Code Online (Sandbox Code Playgroud)
这导致二元谓词
subtypeOf :: Type a -> Type a -> Bool
Run Code Online (Sandbox Code Playgroud)
我现在想用QuickCheck测试这确实做了我想做的事情.但是,以下属性不起作用,因为QuickCheck只是放弃了:
subtypeSanity ? Tree (Type ()) ? Gen Prop
subtypeSanity Node { rootLabel = t, subForest = f } =
let subtypes = concatMap flatten f
in (not $ null subtypes) ==> conjoin
(forAll (elements subtypes) (\x ? x `subtypeOf` t):(map subtypeSanity f))
Run Code Online (Sandbox Code Playgroud)
如果我遗漏了递归调用subtypeSanity,即我传递给列表的尾部 …