Numpy ma wyrafinowaną funkcję indeksowania/krojenia/stopniowania w swoim operatorze dostępu do macierzy. Zobacz: http://docs.scipy.org/doc/numpy/reference/arrays.indexing.htmlZaawansowane indeksowanie/dzielenie Numpy'ego w Haskell
Eksperymentując z Haskellem, pomyślałem, że będzie to edukacyjne, aby spróbować replikować podzbiór tej funkcji indeksowania. Konkretnie to „obiekty do wyboru krotka” lub n-wymiarowa projekcja”(https://en.wikipedia.org/wiki/Projection_%28relational_algebra%29)
Zasadniczo można zrobić.
two_d_array[0:1:1, 0:4:2]
A to daje pierwszy wiersz schodkowy przez 1 zawierający pierwsze 2 kolumny wkroczył przez 2 (pomijam 1 kolumna).
w kolejności słów może wystawać oryginalną 2 wymiarową tablicę do mniejszego 2 wymiarowej tablicy. w rezultacie pozostaje jako 2-wymiarowej tablicy.
Więc oto co próbowałem w Haskell
Rodzaj takiej funkcji powinno być coś takiego:
(!!!) :: (Functor f) => f a -> [(Int, Int, Int)] -> f a
Więc można zobaczyć coś takiego:
three_d_tensor !!! [(s1,e1,st1), (s2,e2,st2), (s3,e3,st3)]
Gdzie sx, ex, STX to początek, koniec, krok odpowiednio.
Przykład powinien wystawać oryginalny tensor do mniejszego tensora, z pierwszym wymiarze ograniczonym przez s1 to e1, stepping by st1
, drugim wymiarze ograniczonym przez s2 to e2, stepping by st2
... itd
Więc oto co mam:
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
Powyższe nie działa z powodu problemu "polimorficznej rekursji". Zasadniczo nie mogę nieskończenie komponować funkcji map
, specyficzne wyrażenie, które to robi jest (projection . map)
. Gdyby możliwy był ten rodzaj rekombinacji polimorficznej, uważam, że zadziała. Jestem jednak otwarty na alternatywne implementacje, które nie wymagają polimorficznej rekursji.
ja zbadali ten problem i wciąż wymyślić krótkie:
- https://byorgey.wordpress.com/2007/08/16/mapping-over-a-nested-functor/
- http://okmij.org/ftp/Haskell/typecast.html#deepest-functor
- Haskell Polymorphic Recursion with Composed Maps causes Infinite Type Error
_Tensors nie są functors_ (zagnieżdżone lub w inny sposób). Tak, czasami jest to coś w rodzaju udawania, i robi to [linear] (http://hackage.haskell.org/package/linear), ale jest to jedna rzecz, w której EKMETT się pomylił, IMO. - Czy naprawdę potrzebujesz rangi zmiennej runtime? – leftaroundabout
Pamiętaj, że ** możesz ** używać polimorficznej rekursji ... pod warunkiem, że 1) typ, który funkcja będzie miała, jest w rzeczywistości możliwy do wyrażenia syntaktycznego i 2) podajesz jawny podpis typu. – Bakuriu
Nie wiem, czy któryś z nich dotyczy, ale wydaje się całkiem interesujący: https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/syntax-extns.html#generalised-list-comprehensions i https://hackage.haskell.org/package/DSH – dfeuer