Haskell 如何横向和向下建造一棵树?

Haskell 如何横向和向下建造一棵树?,haskell,tree,Haskell,Tree,我怎样才能向下和水平地建造一棵树 我有一棵树: data Tree a = Node a [Tree a] 然后,我有一个根Int和[Int] 1 and [2,3,4] 我想造一棵像树一样的树 1 / | \ 2 3 4 /\ / \ /\ 3 4 2 4 2 3 | | | | | | 4 3 4 2 3 2 在哈斯克尔,它看起来像 Node 1 [Node 2 [Node 3 [Node 4 []],Node 4[N

我怎样才能向下和水平地建造一棵树

我有一棵树:

data Tree a = Node a [Tree a]
然后,我有一个根
Int
[Int]

1 and [2,3,4]
我想造一棵像树一样的树

       1
    /  |  \
   2   3   4
  /\  / \  /\
 3  4 2 4 2  3
 |  | | | |  |
 4  3 4 2 3  2 
在哈斯克尔,它看起来像

Node 1 [Node 2 [Node 3 [Node 4 []],Node 4[Node 3 []]], Node 3 [Node 2 [Node 4 []], 
Node 4 [Node 2 []]], Node 4 [Node 2 [Node 3 []], Node 3 [Node 2 []]]]
以下是我尝试过的: 此代码使我的树向下生长

down :: Int -> [Int] -> Tree Int
down y [] = Node y []
down y (x:xs) = Node y [down x xs]
这段代码使我的树横向生长

side :: Int -> [Int] -> Tree Int
side y [] = Node y []
side y x = Node y $ map (\x -> Node x []) y

现在,我很难把它拼在一起得到上面的解决方案。感谢您提供的任何帮助

我们可以引入一个helper函数
pick
,该函数将生成一个包含两个元组的列表,其中包含我们选择的项,并返回剩余的列表。我们可以通过差异列表来实现这一点,但一个简单、效率较低的实现是:

import Data.List(tails, inits)

pick :: [a] -> [(a, [a])]
pick vs = [(x, ws ++ xs) | (ws, (x:xs)) <- zip (inits vs) (tails vs) ]
现在,我们可以更改您的
down
功能:

down :: a -> [a] -> Tree a
down y = Node y . map (uncurry down) . pick
对于给定的样本数据,我们得到:

Prelude Data.List> down 1 [2,3,4]
Node 1 [Node 2 [Node 3 [Node 4 []],Node 4 [Node 3 []]],Node 3 [Node 2 [Node 4 []],Node 4 [Node 2 []]],Node 4 [Node 2 [Node 3 []],Node 3 [Node 2 []]]]

因此,树中的每条路径都是以
1
开头的
[1,2,3,4]
的排列?@chepner-yeah,没错,你遇到了什么麻烦?@MichaelLitchard我不知道如何将树向下和横向生长的代码分割成我想要的树。棘手的是,这样做不仅仅是两种技术的组合。每个级别上可供选择的整数列表会因分支而异。
Prelude Data.List> down 1 [2,3,4]
Node 1 [Node 2 [Node 3 [Node 4 []],Node 4 [Node 3 []]],Node 3 [Node 2 [Node 4 []],Node 4 [Node 2 []]],Node 4 [Node 2 [Node 3 []],Node 3 [Node 2 []]]]