在列表理解中使用数组?

时间:2017-03-06 02:21:25

标签: arrays list haskell list-comprehension

我正在通过The Pearls of Functional Algorithm Design一书。我遇到了一个提供示例的问题。在本书中,作者使用列表理解中的数组,如下所示:

countlist :: [Int] → Array Int Int
countlist xs = accumArray (+) 0 (0, n ) (zip xs (repeat 1))

sort xs = concat [replicate k x | (x,k)←countlist xs]

然后我将这个(经过最小程度的修改)转换为真正的可运行代码:

countlist :: [Int] -> Array Int Int   
countlist xs = accumArray (+) 0 (0, n)(zip xs (repeat 1))
               where n = length xs 

sortLinearTime :: [Int] -> [Int]
sortLinearTime xs = concat [replicate k x | (x, k) <- countlist xs]

然而,这不能编译:

Couldn't match expected type ‘[(Int, Int)]’
                  with actual type ‘Array Int Int’
    • In the expression: countlist xs
      In a stmt of a list comprehension: (x, k) <- countlist xs
      In the first argument of ‘concat’, namely
        ‘[replicate k x | (x, k) <- countlist xs]’

使用ghci构建一个最小的例子:

import Data.Array
let arr = accumArray (+) 0 (0, 7) [(0,1),(1,1),(2,1),(3,1),(4,1),(5,1),(6,1)]
[x | (k, x) <- arr]

结果是:

Couldn't match expected type ‘[(t0, t)]’
            with actual type ‘Array Integer Integer’
Relevant bindings include it :: [t] (bound at <interactive>:38:1)
In the expression: arr
In a stmt of a list comprehension: (k, x) <- arr

那么我怎样才能在列表理解中使用Data.Array

1 个答案:

答案 0 :(得分:4)

我相信您正在寻找indiceselemsassoc

Prelude> import Data.Array
Prelude Data.Array> let arr = accumArray (+) 0 (0, 7) [(0,1),(1,1),(2,1),(3,1),(4,1),(5,1),(6,1)]
Prelude Data.Array> indices arr
[0,1,2,3,4,5,6,7]
Prelude Data.Array> elems arr
[1,1,1,1,1,1,1,0]
Prelude Data.Array> [2*k + x | (k, x) <- assocs arr]
[1,3,5,7,9,11,13,14]

最后一篇介绍如何编写通用列表推导。

有关详细信息,请参阅documentation of Data.Array