如何使用镜头拍摄2D切片

时间:2015-04-25 09:26:43

标签: haskell slice lens

import qualified Data.Vector as V
import Control.Lens
import Data.Vector.Lens

v = V.fromList [V.fromList [1..3], V.fromList [4..6], V.fromList [7..9]]

1D切片(例如):

*Main> v ^. sliced 1 2
fromList [fromList [4,5,6],fromList [7,8,9]]

2D sclice:我应该写什么才能得到这个结果?

*Main> v ^. sliced 1 2 {- ??????? -}  sliced 0 2   --  Or not so?
V.fromList [V.fromList [4,5], V.fromList [7,8]]

1 个答案:

答案 0 :(得分:3)

这应该这样做

insliced :: Int -> Int -> Lens' (V.Vector (V.Vector a)) (V.Vector (V.Vector a))
insliced i n f m = f (V.map (V.slice i n) m)
    <&> V.zipWith (\a b -> a V.// zip [i..i+n-1] (V.toList b)) m

然后

λ v ^. sliced 1 2 . insliced 0 2
fromList [fromList [4,5],fromList [7,8]]

这与sliced的要求类似。

值得一提的是column中有一个名为linear的通用版本。它不能与Vector一起使用,因为Vector不是Representable(因为它的大小不是静态知道的)。但是有V3

之类的东西
λ V3 (V3 1 2 3) (V3 4 5 6) (V3 7 8 9) ^. _yz . column _xy
V2 (V2 4 5) (V2 7 8)

您可以为矢量编写自己的(不太安全)版本:

vcolumn :: ALens' a b -> Lens' (V.Vector a) (V.Vector b)
vcolumn l f m = f (V.map (^# l) m) <&> V.zipWith (\a b -> a & l #~ b) m