Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 生成所有可能的树_Haskell_Binary Tree_List Comprehension_Catalan - Fatal编程技术网

Haskell 生成所有可能的树

Haskell 生成所有可能的树,haskell,binary-tree,list-comprehension,catalan,Haskell,Binary Tree,List Comprehension,Catalan,给定以下数据类型定义: data FormTree = Empty | Node FormTree FormTree deriving Show 我想写一个函数,它生成一个无限列表,其中包含按长度排序的所有可能的树,例如节点数量 下面的代码几乎满足了我的需要,但它只是通过每次插入额外的节点来从右侧的树上向下延伸,但我需要它在两侧交替 allPossibleTrees :: [FormTree] allPossibleTrees = Empty : [Node x y | x <- rec

给定以下数据类型定义:

data FormTree = Empty | Node FormTree FormTree deriving Show
我想写一个函数,它生成一个无限列表,其中包含按长度排序的所有可能的树,例如节点数量

下面的代码几乎满足了我的需要,但它只是通过每次插入额外的节点来从右侧的树上向下延伸,但我需要它在两侧交替

allPossibleTrees :: [FormTree]
allPossibleTrees = Empty : [Node x y | x <- recursive, y <- recursive]
    where recursive = allPossibleTrees
给出:

[Empty,Node Empty Empty,Node Empty (Node Empty Empty),Node Empty (Node Empty (Nodes Empty Empty)),Node Empty (Node Empty (Node Empty (Node Empty Empty)))]
但应该是这样的:

[Empty,Node Empty Empty,Node (Node Empty Empty) Empty,Node Empty (Node Empty Empty),Node (Node Empty Empty) (Node Empty Empty)]
列表理解

[ (x,y) | x<-[1..] , y<-[1..] ]

[(x,y)|x一种方法是跟踪树的大小(即使用的
节点
构造函数的数量)

假设您有这样一个函数,它使用n个节点构造函数返回树:

treesOfSize :: Int -> [FormTree]
然后,
所有树
可以定义为:

allTrees = concatMap treesOfSize [0..]
treesOfSize
的定义可以递归定义,我将让您了解:

treesOfSize 0 = [Empty]
treesOfSize n = [ Node t1 t2 | ... ]

这是一个很好的技巧,让人想起标准的斐波那契数字技巧。我们将构建一个惰性列表;列表中的每个成员将是一个具有给定节点数的所有树的列表。只有一棵树没有节点,
为空,这将作为我们的基本情况。要构建具有
n
节点的所有树,我们假设我知道如何用
0
1
2
,…,
n-1
节点构建树。然后,我们将不确定地选择一对与
n-1
求和的节点,并在顶部粘贴一个
节点

代码:

import Control.Monad
import Data.List

sizes :: [[FormTree]]
sizes = [Empty] : (map go . drop 1 . inits) sizes where
    go smaller = do
      (ls, rs) <- zip smaller (reverse smaller)
      liftM2 Node ls rs
我们可以做一个快速的健康检查:

*Main> take 10 (map length sizes)
[1,1,2,5,14,42,132,429,1430,4862]

…这确实是前十个,所以我们可能答对了!

control monad omega
库似乎对您的原始代码起到了作用:

{-# LANGUAGE MonadComprehensions #-}

import Control.Monad.Omega

data Empty = Empty | Node Empty Empty deriving Show

allPossibleTrees :: [Empty]
allPossibleTrees = Empty : 
    runOmega [Node x y | x <- each allPossibleTrees, y <- each allPossibleTrees]

是的,但是第十一个…
拿11个。地图大小$allPossibleTrees=[0,1,2,2,3,3,3,4,4,3]
。哇!
*Main> take 10 (map length sizes)
[1,1,2,5,14,42,132,429,1430,4862]
{-# LANGUAGE MonadComprehensions #-}

import Control.Monad.Omega

data Empty = Empty | Node Empty Empty deriving Show

allPossibleTrees :: [Empty]
allPossibleTrees = Empty : 
    runOmega [Node x y | x <- each allPossibleTrees, y <- each allPossibleTrees]
*Main> mapM_ print $ take 10 allPossibleTrees 
Empty
Node Empty Empty
Node Empty (Node Empty Empty)
Node (Node Empty Empty) Empty
Node Empty (Node Empty (Node Empty Empty))
Node (Node Empty Empty) (Node Empty Empty)
Node (Node Empty (Node Empty Empty)) Empty
Node Empty (Node (Node Empty Empty) Empty)
Node (Node Empty Empty) (Node Empty (Node Empty Empty))
Node (Node Empty (Node Empty Empty)) (Node Empty Empty)