import Data.List
data Tree a = Leaf a | Node (Tree a) a (Tree a) deriving Show
toTree :: Ord a => [a] -> Tree a
toTree xs = Node (balancedTree (take n xs')) (xs'!!n) (balancedTree (drop n xs'))
where
xs' = sort xs
n = middle xs
middle :: Num a => [a] -> a
middle xs = fromIntegral ((length xs `div` 2) + 1)
balancedTree :: Ord a => [a] -> Tree a
balancedTree (x:[]) = Leaf x
balancedTree xs = Node (balancedTree (take n xs')) (xs'!!n) (balancedTree (drop n xs'))
where
xs' = sort xs
n = middle xs
这是我的代码,用于从列表转换为二叉树。我知道有很多错误,但是我只想在开始调试之前获取排序的类型错误。我在“ toTree”方法和“ balancedTree”方法中都收到以下错误,因为它们实际上是相同的,并且在解决错误后将被压缩为一个。
ex7.hs:6:38: error:
* Couldn't match expected type `Int' with actual type `a'
`a' is a rigid type variable bound by
the type signature for:
toTree :: forall a. Ord a => [a] -> Tree a
at ex7.hs:5:1-32
* In the first argument of `take', namely `n'
In the first argument of `balancedTree', namely `(take n xs')'
In the first argument of `Node', namely
`(balancedTree (take n xs'))'
* Relevant bindings include
xs' :: [a] (bound at ex7.hs:8:9)
n :: a (bound at ex7.hs:9:9)
xs :: [a] (bound at ex7.hs:6:8)
toTree :: [a] -> Tree a (bound at ex7.hs:6:1)
|
6 | toTree xs = Node (balancedTree (take n xs')) (xs'!!n) (balancedTree (drop n xs'))
| ^
我已经尝试了几个小时来通过搜索stackOverflow来修复它,但是我无法弄清楚。 “ toTree”的类型声明必须保持不变。树的定义也应保持不变。
我的理解是,“ take”需要一个“ Int”,而我给它一个“ a”。我不知道该如何解决。
答案 0 :(得分:1)
问题是middle
返回a
,而不是Int
。确实:
middle :: Num a => [a] -> a
middle xs = fromIntegral ((length xs `div` 2) + 1)
但是在您的balancedTree
中,您将其用作索引,take n
,drop n
和!! n
要求n
为索引Int
,实际上是:
balancedTree :: Ord a => [a] -> Tree a
balancedTree (x:[]) = Leaf x
balancedTree xs = Node (balancedTree (take n xs')) (xs'!!n) (balancedTree (drop n xs'))
where
xs' = sort xs
n = middle xs
类型签名也没有多大意义。您不仅可以从由数字组成的列表中计算出任何列表的长度,还可以计算长度。因此,您应该构造一个函数,该函数返回列表中间的 index 并使用它。例如:
middle :: [a] -> Int
middle = (length xs `div` 2) + 1
话虽如此,使用length
等通常在Haskell中不是一个好主意。 length
需要 O(n)时间,而且对于无限列表,它将陷入无限循环。通常,如果您使用诸如length
之类的函数,则会有更优雅的解决方案。
与其使用“自上而下”的方法,不如使用“自下而上”的方法,其中遍历所有项目并动态构建Leaf
,然后分组可能更好。 Node
秒内将它们一起放到顶部。