CMC*_*kai 9 polymorphism recursion haskell numpy composition
Numpy在其阵列访问运算符中具有复杂的索引/切片/步进功能.请参阅:http://docs.scipy.org/doc/numpy/reference/arrays.indexing.html
在尝试使用Haskell时,我认为尝试复制此索引功能的子集会很有教育意义.具体来说,它是"元组选择对象"或n维投影"(https://en.wikipedia.org/wiki/Projection_%28relational_algebra%29).
基本上你可以这样做:
two_d_array[0:1:1, 0:4:2]
Run Code Online (Sandbox Code Playgroud)
这将为您提供第一行,步长为1,包含前两列2(跳过1列).
换句话说,它可以将原始的二维数组投影到一个较小的二维数组中.结果仍然是二维数组.
所以这就是我在Haskell中尝试过的.
这样的函数的类型应该是这样的:
(!!!) :: (Functor f) => f a -> [(Int, Int, Int)] -> f a
Run Code Online (Sandbox Code Playgroud)
所以你可以看到类似的东西:
three_d_tensor !!! [(s1,e1,st1), (s2,e2,st2), (s3,e3,st3)]
Run Code Online (Sandbox Code Playgroud)
其中sx,ex,stx分别为start,end,step.
该示例应将原始张量投影为较小的张量,第一维受限制s1 to e1, stepping by st1
,第二维受s2 to e2, stepping by st2
......等限制.
所以这就是我得到的:
slicing from to xs = take (to - from + 1) (drop from xs)
stepping n = map head . takeWhile (not . null) . iterate (drop n)
(!!!) tensor ((start, end, step):tail) =
project (stepSlice start end step tensor) tail map
where
project tensor ((start, end, step):tail) projection =
project (projection (stepSlice start end step) tensor) tail (projection . map)
project tensor [] _ =
tensor
stepSlice start end step tensor =
((stepping step) . (slicing start end)) tensor
Run Code Online (Sandbox Code Playgroud)
由于"多态递归"的问题,上述方法不起作用.基本上我不能无限地组成map
函数,这样做的具体表达是(projection . map)
.如果这种多态递归是可能的,我相信它会起作用.但我愿意接受不涉及多态递归的替代实现.
我已经研究过这个问题,但仍然很简短:
已经存在一种用于从现有值计算新值的类型 - 函数.假设我们有一个索引到结构的函数,我们可以使用它通过将结构应用于结构来索引结构.
(!!!) = flip ($)
infixr 2 !!!
Run Code Online (Sandbox Code Playgroud)
如果我们有一个索引结构的函数和另一个索引任何嵌套结构的函数,我们可以通过fmap
结构上的第二个函数将它们组合在一起,然后应用外部函数.
(!.) :: Functor f => (f b -> g c) -> (a -> b) -> f a -> g c
t !. f = t . fmap f
infixr 5 !.
Run Code Online (Sandbox Code Playgroud)
使用示例3d结构
three_d_tensor :: [[[(Int,Int,Int)]]]
three_d_tensor = [[[(x, y, z) | z <- [0..4]] | y <- [0..3]] | x <- [0..2]]
Run Code Online (Sandbox Code Playgroud)
我们可以看一下它的一个精心制作的切片与切片功能,内置slicing
和stepping
.
example = three_d_tensor !!! slicing 1 2 !. stepping 2 !. stepping 2 . slicing 1 3
Run Code Online (Sandbox Code Playgroud)
结果如何
[[[(1,0,1),(1,0,3)],[(1,2,1),(1,2,3)]],[[(2,0,1),(2,0,3)],[(2,2,1),(2,2,3)]]]
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
201 次 |
最近记录: |