我有这些结构:
data Tree = Leaf Points | Branch Points [Tree]
deriving(Eq,Show)
data Design = Design Tree Tree Int
deriving(Eq,Show)
数据类型Tree
是数据类型Design
的一部分,而Design
包含两个Trees
:
type Points = [(Int,Int,Int,Int)]
design = Design mtree btree 180
我必须找到所有可能的路径:
numberPaths :: Design -> Int
并从Integer
更改第三个Points
,从design
更改180:
type Points = [(Int,Int,Int,Int)]
design = Design mtree btree 180
changeInt :: Design -> Design
答案 0 :(得分:0)
要查找树中的路径数,我们递归地下降树以计算每个节点的子路径数,然后将它们相加。因此除了使用numberPaths
作为接口之外,我们还需要另一个类型签名为Tree -> Int
的辅助函数。我们称之为descend
。
descend :: Tree -> Int
我们将Leaf
计为1,将Branch
计为其子树的路径数之和。所以descend
变为:
descend :: Tree -> Int
descend (Leaf _) = 1
descend (Branch _ subtress) = foldr (\tree sum -> sum + descend tree) 0 subtrees
函数numberPaths
只需要调用descend
来计算其两棵树。
numberPaths :: Design -> Int
numberPaths (Design a b _) = descend a + descend b
changeInt
的类型签名表示没有引入Int
值来更改Design
类型。我认为这没有意义,所以我冒昧地将其改为Int -> Design -> Design
。
changeInt
的实现遵循类似的模式。为了更改树,我们递归地沿着树的每个级别向下走。我们还引入了辅助函数changePoints
。
changeTree :: Int -> Tree -> Tree
changeTree n (Leaf points) = Leaf $ changePoints n points
changeTree n (Branch points subtrees) = Branch points' subtrees'
where points' = changePoints n points
subtrees' = map (changeTree n) subtrees
changePoints :: Int -> Points -> Points
changePoints n points = map (\(x, y, _, z) -> (x, y, n, z)) points
changeInt
只需要调用changeTree
即可完成工作。
changeInt :: Int -> Design -> Design
changeInt n (Design mtree btree _) = Design mtree' btree' n
where mtree' = changeTree n mtree
btree' = changeTree n btree