uniplate 的 `universeBi` 可以用于以广度优先的方式检索节点吗?
Can uniplate's `universeBi` be used to retrieve nodes in a breadth-first fashion?
是否可以使用 Uniplate 的 universeBi
以广度优先顺序获得输出?结果似乎以深度优先的方式返回。我想知道如何使用 uniplate 以广度优先的方式检索 universeBi
。
为了说明,请考虑以下玩具程序:
{-# LANGUAGE DeriveDataTypeable #-}
import Data.Data
import Data.Generics.Uniplate.Data
data A = A B Int deriving (Data, Typeable)
data B = B Int deriving (Data, Typeable)
val :: A
val = A (B 1) 2
ints :: [Int]
ints = universeBi val
我得到:
*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]
和
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]]
我不确定是否真的保证 Str
准确反映了数据类型的结构,但看起来确实如此。如果必须的话,你可以用 Data
原语做一些东西。
是否可以使用 Uniplate 的 universeBi
以广度优先顺序获得输出?结果似乎以深度优先的方式返回。我想知道如何使用 uniplate 以广度优先的方式检索 universeBi
。
为了说明,请考虑以下玩具程序:
{-# LANGUAGE DeriveDataTypeable #-}
import Data.Data
import Data.Generics.Uniplate.Data
data A = A B Int deriving (Data, Typeable)
data B = B Int deriving (Data, Typeable)
val :: A
val = A (B 1) 2
ints :: [Int]
ints = universeBi val
我得到:
*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]
和
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]]
我不确定是否真的保证 Str
准确反映了数据类型的结构,但看起来确实如此。如果必须的话,你可以用 Data
原语做一些东西。