我正在通过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
?
答案 0 :(得分:4)
我相信您正在寻找indices
,elems
或assoc
:
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
。