在Haskell中创建一个数组

时间:2012-01-17 23:01:06

标签: arrays haskell

我可以使用:

构造一个数组
array ((0,0),(10,10)) [((x,y),(x)) | x<-[0..10], y<-[0..10]]

但是我无法使用函数构造它,甚至不能像以下那样简单:

array ((0,0),(10,10)) [((x,y),f(x)) | x<-[0..10], y<-[0..10]]

这有什么问题?具体来说,如何将“x”转换为Realfrac?

修改 - 没关系,我使用function fromIntegral(num) num代替function (fromIntegral num) num

2 个答案:

答案 0 :(得分:3)

索引类型必须属于Ix类。出于可以理解的原因,没有DoubleFloat等类型的实例。但是你试图乘以Fractional数字。您必须将索引转换为适当的类型,((x,y), fromIntegral x * 1.5)应该有效。

答案 1 :(得分:3)

问题在于,当你说(x*1.5)时,你强迫x成为一个分数 - 例如Float,Double或Rational - 因为(*)取两个值相同类型并返回相同类型的值,当然1.5是小数。

问题出现是因为你不能用浮点数来建立一个数组,只有整数,整数元组等等。 1 你可能想要做的是将xy保留为整数,但转换为小数类型以计算值:

array ((0,0),(10,10)) [((x,y), fromIntegral x * 1.5) | x<-[0..10], y<-[0..10]]

此处xy是整数,但fromIntegral x是Double。 2 fromIntegral做的是转换任何积分类型(比如Int,Int64或Integer)到任何Num(在本例中为Double):

fromIntegral :: (Integral a, Num b) => a -> b

最终结果是一个由(Integer, Integer)索引的数组,其值为Double,这可能是你想要的第一个。 :)

1 具体来说,Ix类型的任何实例都可以;您可以看到完整列表in the documentation

2 至于为什么选择Integer和Double而不是任何其他Integral或Fractional,这是由于Haskell的默认机制。基本上,如果你的程序中有一个模糊的数字类型,它首先尝试使用Integer,如果这不起作用(例如因为类型必须是Fractional,正如我们已经建立的那样,Integer不是),Double是试过而已。这是相当随意的,但有助于消除歧义,否则它会在很多愚蠢的地方出现。