Haskell UArray变量类型

时间:2013-01-29 23:06:33

标签: haskell

我正在尝试使用非常通用的UArrays编写函数。我想要类型签名:

myFunction :: a -> b -> ((UArray Int a), (UArray Int b))

然而,a和b太笼统了。我希望它们是IArray UArray a的可能实例之一。是否有一些派生类型允许我指定这个?例如,如果Num是一个有效的实例,我可以这样做:

myFunction :: (Num a, Num b) => a -> b -> ((UArray Int a), (UArray Int b))

我想做什么才有意义?

提前致谢!

1 个答案:

答案 0 :(得分:5)

我们需要重复您将要使用的数组方法的约束,例如array等。由于您的索引是固定的,我们知道它们是Ix的实例,我们只需要添加IArray约束:

myFunction :: (IArray UArray a, IArray UArray b)
           => a -> b -> ((UArray Int a), (UArray Int b))

为此,您需要FlexibleContexts(请参阅 7.6.3.2。实例上下文的轻松规则)语言扩展。

您还可以考虑将函数概括为任意数组(而不仅仅是UArray s

myFunction1 :: (IArray arr a, IArray arr b)
            => a -> b -> ((arr Int a), (arr Int b))

或甚至可能是任意索引:

myFunction2 :: (IArray arr a, IArray arr b, Ix i)
            => a -> b -> ((arr i a), (arr i b))

(对于这两个变体,您不需要扩展名。)

由于您可能正在使用UArray来提高速度,因此我建议添加INLINE pragma,以便针对您使用它的地方的特定数据类型优化您的函数。这可以显着提高速度。