如何遍历树结构并更改其数据类型

时间:2019-02-08 11:41:17

标签: haskell type-conversion binary-tree huffman-code

我正在尝试在haskell中实现霍夫曼编码,并使用以下两个数据结构:

data Htree = Leaf Char | Branch Htree Htree deriving Show
data Wtree = L Integer Char | B Integer Wtree Wtree deriving Show

首先根据每个字符的频率/权重创建Wtree。 在构造完Wtree之后,我们知道了树的结构,我不再需要每个叶子/分支的权重,因此我想将Wtree转换为Htree,但是在解决这个问题上遇到了麻烦。

createHtree :: Wtree -> Htree
createHtree(L _ char) = Leaf char
createHtree(B _ w1 w2) = Branch createHtree(w1) createHtree(w2)

这是我尝试的解决方案,但无法编译

预期的结果是,正如我提到的,从Wtree到Htree的转换只需要删除Wtree的Integer部分。

1 个答案:

答案 0 :(得分:4)

您可以通过仅使用一种数据类型并通过希望在每个节点上存储的数据类型对其进行参数化来使此任务更简单:

data HTree a = Leaf a Char | Branch a (HTree a) (HTree a)

然后,您的加权树为HTree Integer,而未加权的树为HTree (),表示您不希望在树中存储任何额外的数据。这样,Haskell可以清楚地看到您的两种类型是紧密相关的-使用问题中发布的代码,它们似乎是两种完全不相关的类型。如果另外打开一种无害的语言扩展,则可以使用这种紧密的关系来避免自己编写转换!

{-# LANGUAGE DeriveFunctor #-}

import Data.Functor ((<$))

data HTree a = Leaf a Char
             | Branch a (HTree a) (HTree a)
             deriving Functor

stripLabels :: HTree a -> HTree ()
stripLabels = (() <$)

现在发现stripLabels非常简单,您甚至不需要定义它:您可以在使用站点内联它。