2011-11-19 21 views
4

我已经写了一些代码,其中一小部分代码需要一个大的一维Unboxed.Vector并将它们作为一个Vector(Vector a)返回。Haskell:如何使用“为Unbox A添加实例声明”修复使用Unboxed Vectors时的错误?

部分代码出错。以下是一段与实际代码类似的代码示例,并提供相同的错误。

import Data.Vector.Unboxed as D 


xs = [0,1,2,3,4,5,6,7,8,9,10,11] 
rows = 3 
cols = 4 

sb = D.fromList xs 

takeRows::Int -> Int -> Vector Int -> Vector (Vector Int) 
takeRows rows cols x0 = D.map (\x -> D.slice x (fromIntegral cols) x0) starts 
         where 
         starts = D.enumFromStepN 0 cols rows 

-- takeRowsList::Int -> Int -> Vector Int -> [Vector Int]               
-- takeRowsList rows cols x0 = Prelude.map (\x -> D.slice x (fromIntegral cols) x0) starts       
-- where                     
-- starts = D.toList . D.enumFromStepN 0 cols $ rows          

误差

No instance for (Unbox (Vector Int)) 
    arising from a use of `D.map' 
Possible fix: add an instance declaration for (Unbox (Vector Int)) 
In the expression: 
    D.map (\ x -> slice x (fromIntegral cols) x0) starts 
In an equation for `takeRows': 
    takeRows rows cols x0 
     = D.map (\ x -> slice x (fromIntegral cols) x0) starts 
     where 
      starts = enumFromStepN 0 cols rows 

我写了一个类似的功能takeRowsList,这使得外部载体的名单,这不会有同样的问题。我还在上面列出了它,但评论说明了这一点,以证明我的问题。

我知道某些函数需要类型定义,当我将它们与Unboxed Vectors一起使用时。但在这种情况下,我很难确定何处放置类型定义。我已经尝试了非常多的类型定义所有内容,并且不断收到上述错误。

在此先感谢您的帮助。

回答

2

你不能有一个拆箱矢量包含另一个矢量。只有某些原始数据类型可以被拆箱,即定义了Unbox实例的那些数据类型。向量不是原始数据类型。

可以做的是让你的函数返回一个正常(盒装)的向量的unboxed向量。

+0

再次击败我。 –

+1

@DanielFischer:虽然我更喜欢你的答案,因为它解释了_why_矢量不能拆箱。 – hammar

+0

啊...对。谢谢你的解释。这很清楚。 – Manju

7

无盒子的矢量需要知道它们的元素的大小,而且这个大小必须是不变的。矢量可以具有不同的大小,因此它们不能是无盒矢量的元素。不过,它们可能是盒装矢量的元素,所以如果列表对你所做的不太好,你可以将它制作成盒装矢量(import qualified Data.Vector as B并用B代替D来限定相关函数)。

+0

感谢您的解释。 – Manju