我正在尝试为我的KdTree
数据结构派生一个可折叠的实例。当我尝试创建toList
函数时,问题就出现了。
toList :: KdTree BBox3 a -> [(BBox3,a)]
toList t = F.foldr (:) [] t
在尝试编译时,我收到了此错误
Couldn't match type ‘a’ with ‘(BBox3, a)’
‘a’ is a rigid type variable bound by
the type signature for toList :: KdTree BBox3 a -> [(BBox3, a)]
at Data/Trees/KdTree/Regions/KThree/KThreeTree.hs:127:13
Expected type: KdTree BBox3 (BBox3, a)
Actual type: KdTree BBox3 a
Relevant bindings include
t :: KdTree BBox3 a
(bound at Data/Trees/KdTree/Regions/KThree/KThreeTree.hs:128:10)
toList :: KdTree BBox3 a -> [(BBox3, a)]
(bound at Data/Trees/KdTree/Regions/KThree/KThreeTree.hs:128:3)
In the third argument of ‘foldr’, namely ‘t’
In the expression: foldr (:) [] t
我认为这是因为可折叠实例没有正确派生,所以我做了一个尖峰以查看正在生成的代码。
但事情就是这样,我的穗工作了。我添加了toList
功能,没有任何抱怨,我无法弄清楚是什么造成了不同。所以,最终,
我将非常感谢如何为我的KdTree BBox a
编写可折叠信息,或者对我的代码中出现问题的一些见解与我的峰值中的正确(但看似相同)代码进行比较。
下面是尖峰,以及我项目代码的链接。
{-# LANGUAGE TypeFamilies, InstanceSigs, DeriveFoldable, DeriveFunctor #-}
import Data.List
import qualified Data.Foldable as F
data BBox3 = BBox3 {
v3x :: Double
, v3y :: Double
, v3z :: Double
}
data AxisX = AxisX
data AxisY = AxisY
data AxisZ = AxisZ
class ( Bounded bbox) => KdTreeRegional bbox where
data Axes bbox :: *
data KdTree bbox :: * -> *
data Leaf bbox :: * -> *
toList :: KdTree bbox a -> [(bbox,a)]
instance KdTreeRegional BBox3 where
data Axes BBox3 = X AxisX | Y AxisY | Z AxisZ
data KdTree BBox3 a
= KdNode {
kdLeft :: KdTree BBox3 a
, nodeBBox :: BBox3
, kdSplit :: (Axes BBox3,Double)
, overlapped :: [(BBox3, a)]
, kdRight :: KdTree BBox3 a
}
| KdLeaf (Maybe (Leaf BBox3 a))
deriving (F.Foldable)
data Leaf BBox3 a = Leaf {
leafBBox :: BBox3
, kdleaf :: [(BBox3,a)]
} deriving (F.Foldable)
toList :: KdTree BBox3 a -> [(BBox3,a)]
toList t = F.foldr (:) [] t
https://github.com/mlitchard/kdtree/blob/stack/Data/Trees/KdTree/Regions/Internal.hs
https://github.com/mlitchard/kdtree/blob/stack/Data/Trees/KdTree/Regions/KThree/KThreeTree.hs
更新:这不编译。我收到了这个错误
The IO action ‘main’ is not defined in module ‘Main’
我将其解释为Warning
,并被忽略。我添加了main = undefined
并收到了我一直以来遇到的同样错误。
答案 0 :(得分:3)
foldr
聚合可折叠结构的最右侧类型参数。
class Foldable t where
foldr :: (a -> b -> b) -> b -> t a -> b
-- ...
在这种情况下,t ~ KdTree BBox3
。您toList
的实施将生成a
s。
toList :: KdTree BBox3 a -> [a]
toList t = F.foldr (:) [] t
(顺便说一下,这个确切的函数已存在于Data.Foldable
模块中。)
鉴于您设置系统的方式,KdTree
作为关联类型,无法使用Foldable
(甚至Bifoldable
)机制来提取{{ 1}}来自BBox3
。你的代码看起来比它应该更复杂 - 你到底想要实现什么?
答案 1 :(得分:1)
所以,最后,我很感激如何为我的
写一个可折叠的线索。KdTree BBox a
toList
函数看起来应该是:
toList :: KdTree BBox3 a -> [(BBox3,a)]
toList (KdLeaf Nothing) = []
toList (KdLeaf (Just leaf)) = kdleaf leaf
toList (KdNode node) = toList (kdLeft node) ++ toList (kdRight node) ++ overlapped node
并且foldr
是:
foldr :: (a -> b -> b) -> b -> KdTree BBox3 a -> b
foldr f z kdtree = foldr f z (toList kdtree)