Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.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_Preorder - Fatal编程技术网

Haskell-树的前序编号

Haskell-树的前序编号,haskell,preorder,Haskell,Preorder,我正在准备非程序语言的考试。我有一个测试任务的例子,我不知道如何解决它 任务如下: 给定两个树结构: data Tree a = Nil1 | Node1 a [Tree a] data NumTree a = Nil2 | Node2 (a,Int) [NumTree a] 写函数 numberTree :: Num a => Tree a -> NumTree a 它将在预订单中返回编号的NumTree a 我试过了,但不知道如何继续 numberTree tree = n

我正在准备非程序语言的考试。我有一个测试任务的例子,我不知道如何解决它

任务如下:

给定两个树结构:

data Tree a = Nil1 | Node1 a [Tree a]
data NumTree a  = Nil2 | Node2 (a,Int) [NumTree a]
写函数

numberTree :: Num a => Tree a -> NumTree a
它将在预订单中返回编号的
NumTree a

我试过了,但不知道如何继续

numberTree tree = numberTree' tree 1

numberTree' :: Num a => Tree a -> Int -> NumTree a
numberTree' Nil1 _ = Nil2
numberTree' (Node1 num list) x = (Node2 (num,x) (myMap x numberTree list))
我不知道如何编写这样的
myMap
,因为它应该返回树和累计的预订单号,但我不知道如何做到这一点

欢迎您提出任何建议。

您可以在此处使用:

mapAccumL
函数的行为类似于
map
foldl
的组合;它将一个函数应用于列表的每个元素,从左到右传递一个累加参数,并将此累加器的最终值与新列表一起返回

查看类型,尝试连接匹配的导线,然后主功能看起来像

import Data.List (mapAccumL)

data Tree a = Nil1 | Node1 a [Tree a]  deriving Show
data NumTree a  = Nil2 | Node2 (a,Int) [NumTree a] deriving Show

numberTree :: Tree a -> NumTree a
numberTree tree = tree2
   where
   (_, [tree2]) = mapAccumL g 1 [tree]
   g n Nil1 = (n, Nil2)
   g n (Node1 x trees) = (z, Node2 (x,n) trees2)
      where
      (z, trees2) = .... 
mapAccumL g(n+1)树

不需要
numa=>
约束。您不访问节点的值,只需对节点进行计数,而不管它们携带什么:

>数字树(节点11.1[节点12.2[节点13.3[],无1],节点14.4[])
Node2(1.1,1)[Node2(2.2,2)[Node2(3.3,3)[],Nil2],Node2(4.4,4)[]


这是对
状态
monad的一个很好的使用,它负责通过访问每个节点的递归调用对用于给每个节点编号的值进行线程化

import Control.Monad
import Control.Monad.State

data Tree a = Nil1 | Node1 a [Tree a] deriving (Show)
data NumTree a = Nil2 | Node2 (a,Int) [NumTree a] deriving (Show)

numberTree :: Tree a -> NumTree a
numberTree Nil1 = Nil2
numberTree tree = evalState (numberTree' tree) 0

-- The state stores the value used to number the root
-- of the current tree. Fetch it with get, and put back
-- the number to use for the next root.
-- numberTree' is then used to number each child tree
-- in order before returning a new NumTree value.

numberTree' :: Tree a -> State Int (NumTree a)
numberTree' Nil1 = return Nil2
numberTree' (Node1 root children) = do rootNum <- get
                                       put (rootNum + 1)
                                       newChildren <- mapM numberTree' children
                                       return (Node2 (root, rootNum) newChildren)
import-Control.Monad
进口控制单体状态
数据树a=Nil1 |节点1A[树a]派生(显示)
数据NumTree a=Nil2 | Node2(a,Int)[NumTree a]派生(Show)
numberTree::树a->NumTree a
numberTree Nil1=Nil2
numberTree树=evalState(numberTree树)0
--状态存储用于对根进行编号的值
--当前树的。用get把它拿来,然后放回去
--用于下一个根的数字。
--然后使用numberTree对每个子树进行编号
--在返回新的NumTree值之前按顺序排序。
numberTree':树a->State Int(NumTree a)
numberTree'Nil1=返回Nil2

numberTree'(Node1 root children)=do rootNum我不明白为什么需要
Num a
约束。我认为您的助手函数应该具有类型
numberTree'::Tree a->Int->(NumTree a,Int)
。谢谢,但我认为它是
numberTree'::Tree a->Int->NumTree a
或者不是?而且
Num a
是因为树中是Num。你的
numberTree
函数不应该关心树元素,它应该只添加数字。非常感谢你的解决方案。它似乎在工作,但在我的ghci中不是
状态
monad。它是如何实现的?@Vojacejo try