我在Haskell中使用this代码kata,我在主题中遇到了问题。
找到索引为单个数值的数组的中点是微不足道的,但Haskell的数组索引可以是Ix类型类的任何实例,包括例如,卡是的元组(Int,Word,Card) Ix的一个实例,但不是Num的实例。
获取数组中点的一种方法是查询其长度,查询索引列表,并删除该列表的一半,但这需要O(n)时间。
有没有人知道在常规时间内进行索引的方法?我觉得应该有一个,因为Ix范围应该用整数范围生成。
答案 0 :(得分:4)
Ix
类型类只需要从类型i
的值注入到Int
的值。 index
与range
一起可以为我们提供逆映射:
index' :: (Ix i) => (i, i) -> Int -> i
index' b x = range b ! x
正如您所看到的,index'
至少在线性时间内进行评估。我们也无法知道range b
的工作时间。它以用户在实例定义中定义的方式进行评估。因此,当且仅当我们有某种index'
在恒定时间内工作时,才能进行所需的优化(获取数组的中点)。由于Ix
类型类没有为我们提供从Int
到i
的恒定时间映射,我们应该向用户询问。考虑下一个代码:
midpoint :: (Ix j) => (Int -> j) -> Array j e -> e
midpoint f a = a ! f middle
where middle = rangeSize (bounds a) `div` 2
现在,采用数组中点的复杂性取决于用户定义的f
的复杂性。因此,如果我们的索引类型i
的值可以在Int
值的恒定时间内评估,反之亦然 - 我们会在恒定时间内获得中点。
还要考虑来自ixmap
的{{1}}函数:
Data.Ix