Haskell Repa --- 带索引的映射

10
假设我想在数组上映射一个函数,但该函数的类型不仅是a -> b,而是a -> Int -> b,也就是说该函数还需要一个索引。我该怎么做呢?
3个回答

8

简短回答,使用traverse

更长的例子:

import qualified Data.Array.Repa as A
import qualified Data.Vector.Unboxed as U

arr1 :: A.Array A.DIM2 Double
arr1 = A.fromVector (A.Z A.:. 2 A.:. 3) $ U.fromList [1::Double,2,3,4,5,6]

arr2 :: A.Array A.DIM2 Double
arr2 = A.traverse arr1 id (\lf i@(A.Z A.:. r A.:. c) -> 
                  (lf i) + (fromIntegral r) + (fromIntegral c))  

arr1 是一个 2x3 的矩阵。 traverse 是一个函数,它接受三个参数:(1) 原始数组,(2) 将源索引映射到目标索引的函数,以及 (3) 一个函数,该函数给出了 (i) 原始数组的查找函数和 (ii) 返回新值的索引。

因此,在这里,arr2 通过添加该特定条目的行和列索引来修改每个原始元素。


8

很好的问题,在Repa教程中没有记录,因此我已经更新了一个新的遍历章节

特别是,traverse可以让你:

  • 更改输出数组的形状
  • 索引任何元素
  • 观察当前元素

这意味着你可以做到像这样的事情:

用它们的行索引替换所有元素

> traverse a id (\_ (Z :. i :. j :. k) -> i) 
[0,0,0,0,0,0,0,0,0
,1,1,1,1,1,1,1,1,1
,2,2,2,2,2,2,2,2,2]

将元素乘以其所在的行

> traverse a id (\f (Z :. i :. j :. k) -> f (Z :. i :. j :. k) * i) 
[0,0,0,0,0,0,0,0,0
,10,11,12,13,14,15,16,17,18
,38,40,42,44,46,48,50,52,54]

等等。 travese 非常强大,而且还可以神奇地并行。

高级:并行图像去色

来自 Repa 教程的示例


2

使用zipWith

zipWith (\idx ele -> if even idx then div ele 2 else ele) [0..] xs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接