我正在尝试实现一个以bfs顺序收集OrdTree中所有值的函数,而且我也很难用它。以下是我到目前为止所提供的内容:
data OrdTree a = OrdTree a [OrdTree a] deriving (Show)
bfsTree :: OrdTree a -> [a]
bfsTree tree =
let
use2DList level list (OrdTree a []) = (list!!level)++[a]
use2DList currentLevel list (OrdTree a (branches)) =
foldl
(\tree theList -> use2DList (currentLevel+1) theList tree)
((list!!currentLevel)++[a])
branches
in
concat (use2DList 0 [] tree)
显然我遇到了一堆我未能弄明白的错误。
currentLevel
变量(特别是在匿名函数中),我也是吗?这样可以吗?或者它只需要使用->
左侧指定的操作数?(list!!position)++[value]
?foldl (use2DList (currentLevel+1)) (list!!currentLevel)++[a]) branches
还是更糟糕?对不起,如果文字太多,我真的很困惑这个东西。
答案 0 :(得分:1)
这是bfs命令的意思吗?
val (OrdTree a _) = a
children (OrdTree _ ts) = ts
bfs :: [OrdTree a] -> [a]
bfs ts = (map val ts) ++ bfs (concatMap children ts)
请注意,我已撰写bfs
来获取Ordtree a
的列表,而不仅仅是一棵树。
bfs
的参数是当前级别的树列表。map val ts
是当前级别的值concatMap children ts
是下一级别的所有树更新:以下是我对您的代码所做的一些分析。
首先它没有编译,所以我开始删除代码,直到编译器停止抱怨,我到达:
data OrdTree a = OrdTree a [OrdTree a] deriving (Show)
bfsTree tree =
let
use2DList level list (OrdTree a []) = [a] ++ (list!!level)
in concat (use2DList 0 [] tree)
请注意bfsTree
上没有类型签名 - 我们将告诉我们签名是什么,它会回复:
bfsTree :: OrdTree [a] -> [a]
这显然不对 - 我们想要OrdTree a -> [a]
。事实证明,罪魁祸首是concat
,所以显然代码应该是:
bfsTree tree =
let
use2DList level list (OrdTree a []) = [a] ++ (list!!level)
in use2DList 0 [] tree
现在我们可以问use2DList
的类型签名是什么,ghc(真正的ghc-mod)响应:
use2DList :: Int -> [[a]] -> OrdTree a -> [a]
现在我们必须弄明白foldl
应该是什么。 foldl
有签名:
foldl :: (s -> t -> s) -> s -> [t] -> s
显然我们折叠分支,即t ~ OrdTree a
,use2DList
的返回类型是[a]
,所以s ~ [a]
,所以{{1}的第一个参数应该看起来像:
foldl
由于您的函数开始(\listofa tree -> ...)
,看起来您必须交换参数。而且就我而言。
主要建议是:
(\tree theList -> ...)
命令来查询推断的函数类型:t
插件或emacs的haskell-mode插件,以便查询程序中的子表达式