Wenn ich nach Haskell komme, versuche ich, so etwas wie Numpys Umformung mit Listen zu reproduzieren . Wenn Sie eine flache Liste haben, formen Sie sie in eine n-dimensionale Liste um:
import numpy as np
a = np.arange(1, 18)
b = a.reshape([-1, 2, 3])
# b =
#
# array([[[ 1, 2, 3],
# [ 4, 5, 6]],
#
# [[ 7, 8, 9],
# [10, 11, 12]],
#
# [[13, 14, 15],
# [16, 17, 18]]])
Ich konnte das Verhalten mit festen Indizes reproduzieren, zB:
*Main> reshape23 [1..18]
[[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]],[[13,14,15],[16,17,18]]]
Mein Code lautet:
takeWithRemainder :: (Integral n) => n -> [a] -> ([a], [a])
takeWithRemainder _ [] = ([], [])
takeWithRemainder 0 xs = ([], xs)
takeWithRemainder n (x:xs) = (x : taken, remaining)
where (taken, remaining) = takeWithRemainder (n-1) xs
chunks :: (Integral n) => n -> [a] -> [[a]]
chunks _ [] = []
chunks chunkSize xs = chunk : chunks chunkSize remainderOfList
where (chunk, remainderOfList) = takeWithRemainder chunkSize xs
reshape23 = chunks 2 . chunks 3
Jetzt kann ich anscheinend keinen Weg finden, dies auf eine beliebige Form zu verallgemeinern. Meine ursprüngliche Idee war eine Falte:
reshape :: (Integral n) => [n] -> [a] -> [b]
reshape ns list = foldr (\n acc -> (chunks n) . acc) id ns list
Aber egal wie ich vorgehe, ich bekomme immer einen Tippfehler vom Compiler. Nach meinem Verständnis besteht das Problem darin, dass der Typ für irgendwann acc
als id
's' abgeleitet wird a -> a
, und es gefällt nicht, dass die Liste der Funktionen in der Falte alle einen anderen (obwohl für die Komposition kompatiblen) Typ hat Unterschrift. Ich habe das gleiche Problem, wenn ich versuche, dies mit Rekursion selbst anstelle einer Falte zu implementieren. Die verwirrte mich , weil ich ursprünglich für die beabsichtigt hatte , [b]
in reshape
‚s - Typ Unterschrift ein Stand-in für‚einen anderen, dissoziierten Typen‘zu sein , die alles von könnten [[a]]
zu [[[[[a]]]]]
.
Wie mache ich das falsch? Gibt es eine Möglichkeit, das von mir beabsichtigte Verhalten tatsächlich zu erreichen, oder ist es einfach falsch, diese Art von "dynamischem" Verhalten überhaupt zu wollen?
(..)
Teilimport Data.Proxy (Proxy(..))
?(..)
bedeutet den Import aller Datentypkonstruktoren und möglicherweise der Datensatzfelder. DaProxy
es nur einen Konstruktor gibt, entspricht diesProxy(Proxy))
@Fyodor Soikins Antwort ist perfekt in Bezug auf die eigentliche Frage. Außer es gibt ein kleines Problem mit der Frage selbst. Listen von Listen sind nicht dasselbe wie ein Array. Es ist ein weit verbreitetes Missverständnis, dass Haskell keine Arrays hat und Sie gezwungen sind, sich mit Listen zu befassen, die nicht weiter von der Wahrheit entfernt sein könnten.
Da die Frage mit markiert ist
array
und es einen Vergleich mit gibtnumpy
, möchte ich eine richtige Antwort hinzufügen, die diese Situation für mehrdimensionale Arrays behandelt. Es gibt einige Array-Bibliotheken im Haskell-Ökosystem, von denen eine istmassiv
Eine
reshape
ähnliche Funktionalität vonnumpy
kann durchresize'
Funktion erreicht werden :quelle