Haskell Can uniplate';s`universeBi`是否用于以广度优先的方式检索节点?

Haskell Can uniplate';s`universeBi`是否用于以广度优先的方式检索节点?,haskell,generic-programming,uniplate,Haskell,Generic Programming,Uniplate,是否可以使用Uniplate的universeBi以宽度优先顺序获得输出?结果似乎是以深度优先的方式返回的。我想知道如何使用uniplate以广度优先的方式检索universeBi 为了说明,考虑下面的玩具程序: {-#语言派生数据类型化} 导入数据 导入Data.Generics.Uniplate.Data 数据A=A B整数派生(数据,可键入) 数据B=B整数派生(数据,可键入) 瓦尔::A val=A(b1)2 ints::[Int] ints=通用比瓦尔 我得到: *Main>

是否可以使用Uniplate的
universeBi
以宽度优先顺序获得输出?结果似乎是以深度优先的方式返回的。我想知道如何使用uniplate以广度优先的方式检索
universeBi

为了说明,考虑下面的玩具程序:

{-#语言派生数据类型化}
导入数据
导入Data.Generics.Uniplate.Data
数据A=A B整数派生(数据,可键入)
数据B=B整数派生(数据,可键入)
瓦尔::A
val=A(b1)2
ints::[Int]
ints=通用比瓦尔
我得到:

*Main> ints
[1,2]

但这是深度优先,因为
1
是从
B
节点获得的。我宁愿按广度优先的顺序,即接收
[2,1]
。这在uniplate中可以实现吗?

您可以深入研究
biplate
返回的
Str
的结构:

layers :: Str a -> [[a]]
layers Zero = []
layers (One x) = [[x]]
layers (Two f x) = catLayers (layers f) ([] : layers x)
  where catLayers [] ys = ys
        catLayers xs [] = xs
        catLayers (x : xs) (y : ys) = (x ++ y) : catLayers xs ys
layersBi :: Biplate from to => from -> [[to]]
layersBi = layers . fst . biplate
breadthBi :: Biplate from to => from -> [to]
breadthBi = concat . layersBi
所以现在

breadthBi (A (B 1) 2) :: [Int]
-- = [2, 1]


我不确定它是否确实保证
Str
准确地反映了数据类型的结构,但它似乎是。如果必须的话,您可以用
数据
原语来制作一些东西。

uniplate似乎不支持这一点,但较低级别的
数据也可以。Data
/sybI不认为您在这里观察的是深度优先,只是从左到右。产品类型的
Biplate
默认实例大致为(伪代码)
Biplate(x,y)=concatTraversals(Biplate x)(Biplate y)
。如果切换
A
字段的顺序,则应以不同的顺序获得
Int
s。@BenjaminHodgson从左到右遍历是深度优先遍历的一种形式(按顺序遍历)?这个例子不是特别说明问题,但我假设OP需要一个函数,可以对
data Tree=Branch Tree Int Tree | Leaf
执行广度优先遍历。对
Branch
参数的重新排列不会使
universeBi
在那里工作。谢谢!我正在寻找一种不需要查看编码“内部”的解决方案,但这似乎是不可能的。
data Tree a = Branch (Tree a) a (Tree a) | Leaf deriving (Data, Typeable)
--       4
--   2       6
-- 1   3   5   7
example = Branch (Branch (Branch Leaf 1 Leaf) 2 (Branch Leaf 3 Leaf)) 4 (Branch (Branch Leaf 5 Leaf) 6 (Branch Leaf 7 Leaf))
(layersBi :: Data a => Tree a -> [[a]]) example
-- = [[],[4],[2,6],[1,3,5,7]]