Haskellに入って、リストでnumpyの再形成のようなものを再現しようとしています。具体的には、フラットリストを指定して、n次元リストに再形成します。
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]]])
固定インデックスで動作を再現することができました。例:
*Main> reshape23 [1..18]
[[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]],[[13,14,15],[16,17,18]]]
私のコードは:
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
今、これを任意の形に一般化する方法を見つけることができないようです。私の元々のアイデアはフォールドをすることでした:
reshape :: (Integral n) => [n] -> [a] -> [b]
reshape ns list = foldr (\n acc -> (chunks n) . acc) id ns list
しかし、どのように処理しても、コンパイラーから常に型エラーが発生します。私の理解から、問題はある時点での型acc
がid
's ie a -> a
であると推論され、フォールド内の関数のリストがすべて異なる(構成には互換性がありますが)型であるという事実が好きではないことです署名。これをフォールドの代わりに自分で再帰的に実装しようとすると、同じ問題が発生します。もともと私が意図していたので、これは私を混乱[b]
にreshape
スタンドインから何もすることができ、 『別の、解離したタイプ』のようにの型シグネチャ[[a]]
に[[[[[a]]]]]
。
これはどうして間違っているのですか?私が意図した動作を実際に達成する方法はありますか、または最初にこの種の「動的」動作が必要なのは明らかに間違っていますか?
(..)
部分はimport Data.Proxy (Proxy(..))
何ですか?