futhask-base (empty) → 0.1.0.0
raw patch · 16 files changed
+2689/−0 lines, 16 filesdep +arraydep +basedep +bytestringsetup-changed
Dependencies added: array, base, bytestring, half, monad-control, mtl, text, transformers-base
Files
- ChangeLog.md +3/−0
- LICENSE +30/−0
- README.md +6/−0
- Setup.hs +2/−0
- futhask-base.cabal +58/−0
- src/Futhask/Array.hs +28/−0
- src/Futhask/Array/Boxed.hs +49/−0
- src/Futhask/Array/Element.hs +214/−0
- src/Futhask/Array/Rank.hs +155/−0
- src/Futhask/Array/Storable.hs +222/−0
- src/Futhask/Array/Tuple.hs +1328/−0
- src/Futhask/Array/Unit.hs +36/−0
- src/Futhask/Context.hs +206/−0
- src/Futhask/Monad.hs +130/−0
- src/Futhask/Object.hs +199/−0
- src/Futhask/PrimTypes.hs +23/−0
+ ChangeLog.md view
@@ -0,0 +1,3 @@+# Changelog for futhask-base++## Unreleased changes
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Gusten Isfeldt (c) 2026++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the name of Author name here nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,6 @@+# futhask-base+Base library for Haskell libraries generated from [Futhark](https://www.futhark-lang.org) libraries with [Futhask](https://gitlab.com/Gusten_Isfeldt/futhask)++## Purpose+`futhask-base` provides classes and functions that can be used by FFI-code generated by `futhask`. `futhask` generates bindings to the functions in the `C`-library, and with those instances of the classes defined here. Some of the functions defined here are highly polymorphic, with long type signatures as they take the library context type as an argument. This is to keep objects locked to their context and to allow the base library to function with multiple generated libraries safely. The generated libraries use type synonyms with the context type preapplied to reduce clutter.+
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ futhask-base.cabal view
@@ -0,0 +1,58 @@+cabal-version: 1.12++name: futhask-base+version: 0.1.0.0+stability: experimental+category: FFI+synopsis: Base library for libraries generated by futhask+description:+ This package contains various class definitions and utility functions + used in libraries generated by futhask. + Futhask is an FFI tool that creates haskell libraries from futhark libraries+ through the futhark C-API, aiming to create a safe, haskell friendly, + interface for high performance computation.+ +homepage: https://gitlab.com/Gusten_Isfeldt/futhask#readme+bug-reports: https://gitlab.com/Gusten_Isfeldt/futhask/issues+author: Gusten Isfeldt+maintainer: isfeldt@kth.se+copyright: 2026 Gusten Isfeldt+license: BSD3+license-file: LICENSE+build-type: Simple+extra-source-files:+ README.md+ ChangeLog.md++source-repository head+ type: git+ location: https://gitlab.com/Gusten_Isfeldt/futhask++library+ exposed-modules:+ Futhask.Array+ Futhask.Array.Rank+ Futhask.Array.Element+ Futhask.Array.Unit+ Futhask.Array.Tuple+ Futhask.Array.Boxed+ Futhask.Array.Storable+ Futhask.Context+ Futhask.Monad+ Futhask.Object+ Futhask.PrimTypes+ other-modules:+ Paths_futhask_base+ hs-source-dirs:+ src+ build-depends:+ base >=4.7 && <5+ , array >= 0.5 && <1+ , bytestring >= 0.12 && <1+ , monad-control >= 1.0 && <2+ , mtl >= 2.3 && <3+ , transformers-base >= 0.4 && <1+ , half >= 0.3 && <1+ , text >= 2.1 && <3+ default-language: Haskell2010+
+ src/Futhask/Array.hs view
@@ -0,0 +1,28 @@+{-|+Haskell Array library for Futhask. In contrast to many other array libraries, +the array structure is uniquely determined by the type of element.+This allows the associated type @Array element@ to be used to unambiguously express any type of valid array.+All arrays are rank one and higher ranks are represented by arrays of arrays, analogue to futhark arrays.+In contrast to futhark arrays, the lack of size types allows for irregular arrays, +however this is not permitted when converting to futhark values. +Instances `Element` are defined for all @Native@ types in the generated libraries.+-}+module Futhask.Array+ ( -- | Defines the `Element` class, instances of which can be elements of arrays and other generic array functions+ module E+ , -- | Unit arrays, defined only by their size+ module U+ , -- | Boxed arrays, used for nesting, and types unsuited for the other array types+ module B+ , -- | Tuple arrays, used tuples of any `Element` instances+ module T + , -- | Storable arrays, used for primitive futhark types+ module S+ ) where+import Futhask.Array.Element as E+import Futhask.Array.Unit as U+import Futhask.Array.Boxed as B+import Futhask.Array.Tuple as T+import Futhask.Array.Storable as S++
+ src/Futhask/Array/Boxed.hs view
@@ -0,0 +1,49 @@+{-# LANGUAGE TypeFamilyDependencies, FlexibleContexts, GADTs, TypeOperators #-}+{-|+Boxed arrays for opaque values and arrays+-}++module Futhask.Array.Boxed where+import Futhask.Array.Element+import qualified Data.Array as A+import qualified Data.Array.Base as UA+import qualified Data.Array.IO as MA+data BArray a where+ BArray :: A.Array Int a -> Int -> Int -> BArray a+data MBArray a where+ MBArray :: MA.IOArray Int a -> Int -> Int -> MBArray a++instance Element (BArray elem) where+ type Array (BArray elem) = BArray (BArray elem)+ type MArray (BArray elem) = MBArray (BArray elem)+ size = sizeB+ unsafeRead = unsafeReadB+ msize = msizeB+ unsafePeek = unsafePeekB+ unsafePoke = unsafePokeB+ scratch = scratchB+ unsafeThaw = unsafeThawB+ unsafeFreeze = unsafeFreezeB+ unsafeSlice = unsafeSliceB++instance (Show a, Element a, BArray a ~ Array a) => Show (BArray a) where+ show = show . toList++sizeB :: BArray a -> Int+sizeB (BArray _ _ sz) = sz+unsafeReadB :: BArray a -> Int -> a+unsafeReadB (BArray a i _) idx = a A.! (i+idx)+msizeB :: MBArray a -> Int+msizeB (MBArray _ _ sz) = sz+unsafePeekB :: MBArray a -> Int -> IO a +unsafePeekB (MBArray a i _) idx = MA.readArray a (i+idx)+unsafePokeB :: MBArray a -> Int -> a -> IO () +unsafePokeB (MBArray a i s) idx elem = MA.writeArray a (i+idx) elem+scratchB :: Int -> IO (MBArray a)+scratchB sz = fmap (\a -> MBArray a 0 sz) (MA.newArray (0, sz-1) undefined)+unsafeThawB :: BArray a -> IO (MBArray a)+unsafeThawB (BArray a i s) = fmap (\a -> MBArray a i s) (UA.unsafeThaw a)+unsafeFreezeB :: MBArray a -> IO (BArray a)+unsafeFreezeB (MBArray a i s) = fmap (\a -> BArray a i s) (UA.unsafeFreeze a)+unsafeSliceB :: BArray a -> Int -> Int -> BArray a+unsafeSliceB (BArray a i _) i0 sz = BArray a (i+i0) sz
+ src/Futhask/Array/Element.hs view
@@ -0,0 +1,214 @@+{-# LANGUAGE TypeFamilyDependencies, FlexibleContexts #-}+{-|+The interface for Haskell arrays, intended to mirror the types of Futhark arrays intuitively.+-}++module Futhask.Array.Element where+import System.IO.Unsafe+import Data.List as L+import Control.Monad (foldM)++-- *Array Type++-- | Defines how an array of something is represented and operated on+class Element elem where+ -- |Immutable Array type+ type Array elem = arr | arr -> elem+ -- |Mutable Array type+ type MArray elem = marr | marr -> elem+ -- |size of Immutable array+ size :: Array elem -> Int+ -- |size of mutable array+ msize :: MArray elem -> Int+ -- |read element without bounds check+ unsafeRead :: Array elem -> Int -> elem+ -- |peek element without bounds check+ unsafePeek :: MArray elem -> Int -> IO elem+ -- |poke element without bounds check+ unsafePoke :: MArray elem -> Int -> elem -> IO ()+ -- |convert array to mutable without copy+ unsafeThaw :: Array elem -> IO (MArray elem)+ -- |convert array to immutable without copy+ unsafeFreeze :: MArray elem -> IO (Array elem)+ -- |slice array, new slice points to the same memory+ unsafeSlice :: Array elem -> Int -> Int -> Array elem+ -- |construct new array from uninitialized memory+ scratch :: Int -> IO (MArray elem)+++-- | read element, throws error on out of bounds index+read :: Element e => Array e -> Int -> e+read arr idx = if 0 <= idx || idx < size arr then unsafeRead arr idx else error "Index is out of bounds"+-- | read element in the `Maybe` monad+readM :: Element e => Array e -> Int -> Maybe e+readM arr idx = if 0 <= idx || idx < size arr then Just (unsafeRead arr idx) else Nothing++-- | peek element, throws error on out of bounds index+peek :: Element e => MArray e -> Int -> IO e+peek arr idx = if 0 <= idx || idx < msize arr then unsafePeek arr idx else error "Index is out of bounds"+-- | peek element in the `Maybe` monad+peekM :: Element e => MArray e -> Int -> Maybe (IO e)+peekM arr idx = if 0 <= idx || idx < msize arr then Just (unsafePeek arr idx) else Nothing++-- | poke element, throws error on out of bounds index+poke :: Element e => MArray e -> Int -> e -> IO ()+poke arr idx elem = if 0 <= idx || idx < msize arr then unsafePoke arr idx elem else error "Index is out of bounds"+-- | poke element in the `Maybe` monad+pokeM :: Element e => MArray e -> Int -> e -> Maybe (IO ())+pokeM arr idx elem = if 0 <= idx || idx < msize arr then Just (unsafePoke arr idx elem) else Nothing++-- | index operator+(!) :: Element e => Array e -> Int -> e+(!) = Futhask.Array.Element.read+-- | index operator in the `Maybe` monad+(!?) :: Element e => Array e -> Int -> Maybe e+(!?) = Futhask.Array.Element.readM++-- | List of valid indices+indices arr = [0..size arr-1]+-- | List of valid indices for mutable array +mindices arr = [0..msize arr-1]++-- *Mutation+copy :: (Element elem) => MArray elem -> IO (MArray elem)+copy arr = do+ arr' <- scratch (msize arr)+ mapM_ (\idx -> unsafePeek arr idx >>= unsafePoke arr' idx) (mindices arr)+ pure arr'++thaw :: Element elem => Array elem -> IO (MArray elem)+thaw a = unsafeThaw a >>= copy++freeze :: Element elem => MArray elem -> IO (Array elem)+freeze a = copy a >>= unsafeFreeze++-- *Reshaping+unflatten :: (Element elem, Element (Array elem)) => Int -> Int -> Array elem -> Array (Array elem)+unflatten m n arr = if size arr == m*n + then tabulate m (\i -> unsafeSlice arr (n*i) n)+ else error "size of array does not fit new dimensions"+unflatten_3d :: (Element elem, Element (Array elem), Element (Array (Array elem))) => Int -> Int -> Int -> Array elem -> Array (Array (Array elem))+unflatten_3d m n l arr = if size arr == m*n*l + then tabulate m (\i -> let o = i*n in tabulate n (\j -> unsafeSlice arr (o+l*j) l))+ else error "size of array does not fit new dimensions"++flatten :: (Element elem, Element (Array elem)) => Array (Array elem) -> Array elem+flatten arr = fromList $ concatMap toList (toList arr)+flatten_3d :: (Element elem, Element (Array elem), Element (Array (Array elem))) => Array (Array (Array elem)) -> Array elem+flatten_3d arr = fromList $ concatMap (concatMap toList . toList) (toList arr)+ ++-- *List conversion+toList :: (Element a) => Array a -> [a]+toList = Futhask.Array.Element.foldr (:) [] +fromList :: (Element a) => [a] -> Array a+fromList list = unsafePerformIO $ do+ arr <- scratch (length list)+ mapM_ (\(i, v) -> unsafePoke arr i v) (zip [0..] list)+ unsafeFreeze arr++-- *Misc Ops +foldl fun acc arr = + L.foldl (\acc -> fun acc . unsafeRead arr) acc (indices arr)+foldr fun acc arr =+ L.foldr (\i acc -> fun (unsafeRead arr i) acc) acc (indices arr)+++scatter :: Element a => Array a -> [Int] -> [a] -> Array a+scatter dest is vs = unsafePerformIO $ do+ dest <- thaw dest+ mapM_ (\(i, v) -> unsafePoke dest i v) (zip is vs)+ unsafeFreeze dest++scan :: Element a => (a -> a -> a) -> a -> Array a -> Array a+scan op neu arr = unsafePerformIO $ do+ arr' <- scratch (size arr)+ foldM (\acc i -> let acc = op acc (unsafeRead arr i) in unsafePoke arr' i acc >> pure acc) neu (indices arr)+ unsafeFreeze arr'++tabulate :: Element elem => Int -> (Int -> elem) -> Array elem+tabulate sz f = unsafePerformIO $ do+ xs <- scratch sz+ mapM_ (\idx -> unsafePoke xs idx (f idx)) [0..sz-1]+ unsafeFreeze xs++replicate sz a = tabulate sz (\_ -> a) ++map :: (Element a, Element b) => (a -> b) -> Array a -> Array b+map f xs = tabulate (size xs) (f . unsafeRead xs)++map2 :: (Element e0, Element e1, Element e2) => (e0 -> e1 -> e2) -> Array e0 -> Array e1 -> Array e2+map2 f a0 a1 = if size a0 == size a1+ then tabulate (size a0) (\idx -> f (unsafeRead a0 idx) (unsafeRead a1 idx))+ else error "sizes of arguments do not match"++map3 :: (Element e0, Element e1, Element e2, Element e3) => (e0 -> e1 -> e2 -> e3) -> Array e0 -> Array e1 -> Array e2 -> Array e3+map3 f a0 a1 a2 = if size a0 == size a1 && size a1 == size a2+ then tabulate (size a0) (\idx -> f (unsafeRead a0 idx) (unsafeRead a1 idx) (unsafeRead a2 idx))+ else error "sizes of arguments do not match"++map4 :: (Element e0, Element e1, Element e2, Element e3, Element e4) => (e0 -> e1 -> e2 -> e3 -> e4) -> Array e0 -> Array e1 -> Array e2 -> Array e3 -> Array e4+map4 f a0 a1 a2 a3 = if size a0 == size a1 && size a1 == size a2 && size a2 == size a3+ then tabulate (size a0) (\idx -> f (unsafeRead a0 idx) (unsafeRead a1 idx) (unsafeRead a2 idx) (unsafeRead a3 idx))+ else error "sizes of arguments do not match"++map5 :: (Element e0, Element e1, Element e2, Element e3, Element e4, Element e5) => (e0 -> e1 -> e2 -> e3 -> e4 -> e5) -> Array e0 -> Array e1 -> Array e2 -> Array e3 -> Array e4 -> Array e5+map5 f a0 a1 a2 a3 a4 = if size a0 == size a1 && size a1 == size a2 && size a2 == size a3 && size a3 == size a4+ then tabulate (size a0) (\idx -> f (unsafeRead a0 idx) (unsafeRead a1 idx) (unsafeRead a2 idx) (unsafeRead a3 idx) (unsafeRead a4 idx))+ else error "sizes of arguments do not match"++map6 :: (Element e0, Element e1, Element e2, Element e3, Element e4, Element e5, Element e6) => (e0 -> e1 -> e2 -> e3 -> e4 -> e5 -> e6) -> Array e0 -> Array e1 -> Array e2 -> Array e3 -> Array e4 -> Array e5 -> Array e6+map6 f a0 a1 a2 a3 a4 a5 = if size a0 == size a1 && size a1 == size a2 && size a2 == size a3 && size a3 == size a4 && size a4 == size a5+ then tabulate (size a0) (\idx -> f (unsafeRead a0 idx) (unsafeRead a1 idx) (unsafeRead a2 idx) (unsafeRead a3 idx) (unsafeRead a4 idx) (unsafeRead a5 idx))+ else error "sizes of arguments do not match"++map7 :: (Element e0, Element e1, Element e2, Element e3, Element e4, Element e5, Element e6, Element e7) => (e0 -> e1 -> e2 -> e3 -> e4 -> e5 -> e6 -> e7) -> Array e0 -> Array e1 -> Array e2 -> Array e3 -> Array e4 -> Array e5 -> Array e6 -> Array e7+map7 f a0 a1 a2 a3 a4 a5 a6 = if size a0 == size a1 && size a1 == size a2 && size a2 == size a3 && size a3 == size a4 && size a4 == size a5 && size a5 == size a6+ then tabulate (size a0) (\idx -> f (unsafeRead a0 idx) (unsafeRead a1 idx) (unsafeRead a2 idx) (unsafeRead a3 idx) (unsafeRead a4 idx) (unsafeRead a5 idx) (unsafeRead a6 idx))+ else error "sizes of arguments do not match"++map8 :: (Element e0, Element e1, Element e2, Element e3, Element e4, Element e5, Element e6, Element e7, Element e8) => (e0 -> e1 -> e2 -> e3 -> e4 -> e5 -> e6 -> e7 -> e8) -> Array e0 -> Array e1 -> Array e2 -> Array e3 -> Array e4 -> Array e5 -> Array e6 -> Array e7 -> Array e8+map8 f a0 a1 a2 a3 a4 a5 a6 a7 = if size a0 == size a1 && size a1 == size a2 && size a2 == size a3 && size a3 == size a4 && size a4 == size a5 && size a5 == size a6 && size a6 == size a7+ then tabulate (size a0) (\idx -> f (unsafeRead a0 idx) (unsafeRead a1 idx) (unsafeRead a2 idx) (unsafeRead a3 idx) (unsafeRead a4 idx) (unsafeRead a5 idx) (unsafeRead a6 idx) (unsafeRead a7 idx))+ else error "sizes of arguments do not match"++map9 :: (Element e0, Element e1, Element e2, Element e3, Element e4, Element e5, Element e6, Element e7, Element e8, Element e9) => (e0 -> e1 -> e2 -> e3 -> e4 -> e5 -> e6 -> e7 -> e8 -> e9) -> Array e0 -> Array e1 -> Array e2 -> Array e3 -> Array e4 -> Array e5 -> Array e6 -> Array e7 -> Array e8 -> Array e9+map9 f a0 a1 a2 a3 a4 a5 a6 a7 a8 = if size a0 == size a1 && size a1 == size a2 && size a2 == size a3 && size a3 == size a4 && size a4 == size a5 && size a5 == size a6 && size a6 == size a7 && size a7 == size a8+ then tabulate (size a0) (\idx -> f (unsafeRead a0 idx) (unsafeRead a1 idx) (unsafeRead a2 idx) (unsafeRead a3 idx) (unsafeRead a4 idx) (unsafeRead a5 idx) (unsafeRead a6 idx) (unsafeRead a7 idx) (unsafeRead a8 idx))+ else error "sizes of arguments do not match"++map10 :: (Element e0, Element e1, Element e2, Element e3, Element e4, Element e5, Element e6, Element e7, Element e8, Element e9, Element e10) => (e0 -> e1 -> e2 -> e3 -> e4 -> e5 -> e6 -> e7 -> e8 -> e9 -> e10) -> Array e0 -> Array e1 -> Array e2 -> Array e3 -> Array e4 -> Array e5 -> Array e6 -> Array e7 -> Array e8 -> Array e9 -> Array e10+map10 f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 = if size a0 == size a1 && size a1 == size a2 && size a2 == size a3 && size a3 == size a4 && size a4 == size a5 && size a5 == size a6 && size a6 == size a7 && size a7 == size a8 && size a8 == size a9+ then tabulate (size a0) (\idx -> f (unsafeRead a0 idx) (unsafeRead a1 idx) (unsafeRead a2 idx) (unsafeRead a3 idx) (unsafeRead a4 idx) (unsafeRead a5 idx) (unsafeRead a6 idx) (unsafeRead a7 idx) (unsafeRead a8 idx) (unsafeRead a9 idx))+ else error "sizes of arguments do not match"++map11 :: (Element e0, Element e1, Element e2, Element e3, Element e4, Element e5, Element e6, Element e7, Element e8, Element e9, Element e10, Element e11) => (e0 -> e1 -> e2 -> e3 -> e4 -> e5 -> e6 -> e7 -> e8 -> e9 -> e10 -> e11) -> Array e0 -> Array e1 -> Array e2 -> Array e3 -> Array e4 -> Array e5 -> Array e6 -> Array e7 -> Array e8 -> Array e9 -> Array e10 -> Array e11+map11 f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 = if size a0 == size a1 && size a1 == size a2 && size a2 == size a3 && size a3 == size a4 && size a4 == size a5 && size a5 == size a6 && size a6 == size a7 && size a7 == size a8 && size a8 == size a9 && size a9 == size a10+ then tabulate (size a0) (\idx -> f (unsafeRead a0 idx) (unsafeRead a1 idx) (unsafeRead a2 idx) (unsafeRead a3 idx) (unsafeRead a4 idx) (unsafeRead a5 idx) (unsafeRead a6 idx) (unsafeRead a7 idx) (unsafeRead a8 idx) (unsafeRead a9 idx) (unsafeRead a10 idx))+ else error "sizes of arguments do not match"++map12 :: (Element e0, Element e1, Element e2, Element e3, Element e4, Element e5, Element e6, Element e7, Element e8, Element e9, Element e10, Element e11, Element e12) => (e0 -> e1 -> e2 -> e3 -> e4 -> e5 -> e6 -> e7 -> e8 -> e9 -> e10 -> e11 -> e12) -> Array e0 -> Array e1 -> Array e2 -> Array e3 -> Array e4 -> Array e5 -> Array e6 -> Array e7 -> Array e8 -> Array e9 -> Array e10 -> Array e11 -> Array e12+map12 f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 = if size a0 == size a1 && size a1 == size a2 && size a2 == size a3 && size a3 == size a4 && size a4 == size a5 && size a5 == size a6 && size a6 == size a7 && size a7 == size a8 && size a8 == size a9 && size a9 == size a10 && size a10 == size a11+ then tabulate (size a0) (\idx -> f (unsafeRead a0 idx) (unsafeRead a1 idx) (unsafeRead a2 idx) (unsafeRead a3 idx) (unsafeRead a4 idx) (unsafeRead a5 idx) (unsafeRead a6 idx) (unsafeRead a7 idx) (unsafeRead a8 idx) (unsafeRead a9 idx) (unsafeRead a10 idx) (unsafeRead a11 idx))+ else error "sizes of arguments do not match"++map13 :: (Element e0, Element e1, Element e2, Element e3, Element e4, Element e5, Element e6, Element e7, Element e8, Element e9, Element e10, Element e11, Element e12, Element e13) => (e0 -> e1 -> e2 -> e3 -> e4 -> e5 -> e6 -> e7 -> e8 -> e9 -> e10 -> e11 -> e12 -> e13) -> Array e0 -> Array e1 -> Array e2 -> Array e3 -> Array e4 -> Array e5 -> Array e6 -> Array e7 -> Array e8 -> Array e9 -> Array e10 -> Array e11 -> Array e12 -> Array e13+map13 f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 = if size a0 == size a1 && size a1 == size a2 && size a2 == size a3 && size a3 == size a4 && size a4 == size a5 && size a5 == size a6 && size a6 == size a7 && size a7 == size a8 && size a8 == size a9 && size a9 == size a10 && size a10 == size a11 && size a11 == size a12+ then tabulate (size a0) (\idx -> f (unsafeRead a0 idx) (unsafeRead a1 idx) (unsafeRead a2 idx) (unsafeRead a3 idx) (unsafeRead a4 idx) (unsafeRead a5 idx) (unsafeRead a6 idx) (unsafeRead a7 idx) (unsafeRead a8 idx) (unsafeRead a9 idx) (unsafeRead a10 idx) (unsafeRead a11 idx) (unsafeRead a12 idx))+ else error "sizes of arguments do not match"++map14 :: (Element e0, Element e1, Element e2, Element e3, Element e4, Element e5, Element e6, Element e7, Element e8, Element e9, Element e10, Element e11, Element e12, Element e13, Element e14) => (e0 -> e1 -> e2 -> e3 -> e4 -> e5 -> e6 -> e7 -> e8 -> e9 -> e10 -> e11 -> e12 -> e13 -> e14) -> Array e0 -> Array e1 -> Array e2 -> Array e3 -> Array e4 -> Array e5 -> Array e6 -> Array e7 -> Array e8 -> Array e9 -> Array e10 -> Array e11 -> Array e12 -> Array e13 -> Array e14+map14 f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 = if size a0 == size a1 && size a1 == size a2 && size a2 == size a3 && size a3 == size a4 && size a4 == size a5 && size a5 == size a6 && size a6 == size a7 && size a7 == size a8 && size a8 == size a9 && size a9 == size a10 && size a10 == size a11 && size a11 == size a12 && size a12 == size a13+ then tabulate (size a0) (\idx -> f (unsafeRead a0 idx) (unsafeRead a1 idx) (unsafeRead a2 idx) (unsafeRead a3 idx) (unsafeRead a4 idx) (unsafeRead a5 idx) (unsafeRead a6 idx) (unsafeRead a7 idx) (unsafeRead a8 idx) (unsafeRead a9 idx) (unsafeRead a10 idx) (unsafeRead a11 idx) (unsafeRead a12 idx) (unsafeRead a13 idx))+ else error "sizes of arguments do not match"++map15 :: (Element e0, Element e1, Element e2, Element e3, Element e4, Element e5, Element e6, Element e7, Element e8, Element e9, Element e10, Element e11, Element e12, Element e13, Element e14, Element e15) => (e0 -> e1 -> e2 -> e3 -> e4 -> e5 -> e6 -> e7 -> e8 -> e9 -> e10 -> e11 -> e12 -> e13 -> e14 -> e15) -> Array e0 -> Array e1 -> Array e2 -> Array e3 -> Array e4 -> Array e5 -> Array e6 -> Array e7 -> Array e8 -> Array e9 -> Array e10 -> Array e11 -> Array e12 -> Array e13 -> Array e14 -> Array e15+map15 f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 = if size a0 == size a1 && size a1 == size a2 && size a2 == size a3 && size a3 == size a4 && size a4 == size a5 && size a5 == size a6 && size a6 == size a7 && size a7 == size a8 && size a8 == size a9 && size a9 == size a10 && size a10 == size a11 && size a11 == size a12 && size a12 == size a13 && size a13 == size a14+ then tabulate (size a0) (\idx -> f (unsafeRead a0 idx) (unsafeRead a1 idx) (unsafeRead a2 idx) (unsafeRead a3 idx) (unsafeRead a4 idx) (unsafeRead a5 idx) (unsafeRead a6 idx) (unsafeRead a7 idx) (unsafeRead a8 idx) (unsafeRead a9 idx) (unsafeRead a10 idx) (unsafeRead a11 idx) (unsafeRead a12 idx) (unsafeRead a13 idx) (unsafeRead a14 idx))+ else error "sizes of arguments do not match"++map16 :: (Element e0, Element e1, Element e2, Element e3, Element e4, Element e5, Element e6, Element e7, Element e8, Element e9, Element e10, Element e11, Element e12, Element e13, Element e14, Element e15, Element e16) => (e0 -> e1 -> e2 -> e3 -> e4 -> e5 -> e6 -> e7 -> e8 -> e9 -> e10 -> e11 -> e12 -> e13 -> e14 -> e15 -> e16) -> Array e0 -> Array e1 -> Array e2 -> Array e3 -> Array e4 -> Array e5 -> Array e6 -> Array e7 -> Array e8 -> Array e9 -> Array e10 -> Array e11 -> Array e12 -> Array e13 -> Array e14 -> Array e15 -> Array e16+map16 f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 = if size a0 == size a1 && size a1 == size a2 && size a2 == size a3 && size a3 == size a4 && size a4 == size a5 && size a5 == size a6 && size a6 == size a7 && size a7 == size a8 && size a8 == size a9 && size a9 == size a10 && size a10 == size a11 && size a11 == size a12 && size a12 == size a13 && size a13 == size a14 && size a14 == size a15+ then tabulate (size a0) (\idx -> f (unsafeRead a0 idx) (unsafeRead a1 idx) (unsafeRead a2 idx) (unsafeRead a3 idx) (unsafeRead a4 idx) (unsafeRead a5 idx) (unsafeRead a6 idx) (unsafeRead a7 idx) (unsafeRead a8 idx) (unsafeRead a9 idx) (unsafeRead a10 idx) (unsafeRead a11 idx) (unsafeRead a12 idx) (unsafeRead a13 idx) (unsafeRead a14 idx) (unsafeRead a15 idx))+ else error "sizes of arguments do not match"+
+ src/Futhask/Array/Rank.hs view
@@ -0,0 +1,155 @@+{-# LANGUAGE RankNTypes, ExistentialQuantification, FlexibleInstances, UndecidableInstances, TypeFamilyDependencies, MultiParamTypeClasses, ScopedTypeVariables, FlexibleContexts, FunctionalDependencies, ConstraintKinds, QuantifiedConstraints, TypeOperators #-}+module Futhask.Array.Rank where+import Data.Int+import Foreign.Ptr+import Foreign.Storable+import System.IO.Unsafe++ +class Dim r where+ type Size r = res | res -> r + type Index r = res | res -> r+ type DimFun r a = res | res -> r+ type List r a + sizeAsArgs :: DimFun r a -> Size r -> IO a+ sizeFromPointer :: Ptr Int64 -> IO (Size r)+ inBounds :: Size r -> Index r -> Bool+ linearSize :: Size r -> Int + linearIndex :: Size r -> Index r -> Int+ sizeString :: Size r -> String+ indexString :: Index r -> String+ indices :: Size r -> [Index r]+ mapToList :: (Index r -> a) -> Size r -> List r a+ifInBounds s i a = if inBounds s i + then a + else error ("Index " ++ indexString i ++ " out of bounds of array with size " ++ sizeString s ++ ".")+maybeInBounds s i a = if inBounds s i then Just a else Nothing+data R0+data R1+data R2+data R3+data R4+--data Rx+---- recursive indextype+--instance (Dim R) => Rx R +-- type Size (Rx R) = (Int, Size R)+-- type Index (Rx R) = (Int, Index R)+-- inBounds = +-- linearSize+-- linearIndex+instance Dim R0 where+ type Size R0 = ()+ type Index R0 = ()+ type DimFun R0 a = IO a+ type List R0 a = a+ sizeAsArgs df s = df+ sizeFromPointer _ = return ()+ inBounds _ _ = True+ linearSize _ = 1+ linearIndex _ _ = 0 + sizeString s = "()"+ indexString i = "()"+ indices s = [()]+ mapToList f s = f () +instance Dim R1 where+ type Size R1 = Int+ type Index R1 = Int+ type DimFun R1 a = Int64 -> IO a+ type List R1 a = [a]+ sizeAsArgs df s = df (fromIntegral s) + sizeFromPointer p = fmap fromIntegral (peek p)+ inBounds s i = 0 <= i && i < s++ linearSize s = s+ linearIndex _ i = i+ sizeString s = show s+ indexString i = show i+ indices s = [0..s-1]+ mapToList f s = map f [0..s-1]+instance Dim R2 where+ type Size R2 = (Int, Int)+ type Index R2 = (Int, Int)+ type DimFun R2 a = Int64 -> Int64 -> IO a+ type List R2 a = [[a]]+ sizeAsArgs df (s0, s1) = df (fromIntegral s0) (fromIntegral s1)+ sizeFromPointer p = do+ s0 <- fmap fromIntegral (peekElemOff p 0)+ s1 <- fmap fromIntegral (peekElemOff p 1)+ return (s0, s1)+ inBounds (s0, s1) (i0, i1) = inBounds s0 i0 && inBounds s1 i1+ linearSize (s0, s1) = linearSize s0 * s1+ linearIndex (s0, s1) (i0, i1) = linearIndex s0 i0 * s1 + i1+ sizeString s = show s+ indexString i = show i+ indices (s0, s1) = (,) <$> [0..s0-1] <*> [0..s1-1]+ mapToList f (s0, s1) = map (\i0 -> map (\i1 -> f (i0, i1))[0..s1-1]) [0..s0-1]+ +instance Dim R3 where+ type Size R3 = (Int, Int, Int)+ type Index R3 = (Int, Int, Int)+ type DimFun R3 a = Int64 -> Int64 -> Int64 -> IO a+ type List R3 a = [[[a]]]+ sizeAsArgs df (s0, s1, s2) = df (fromIntegral s0) (fromIntegral s1) (fromIntegral s2)+ sizeFromPointer p = do+ s0 <- fmap fromIntegral (peekElemOff p 0)+ s1 <- fmap fromIntegral (peekElemOff p 1)+ s2 <- fmap fromIntegral (peekElemOff p 2)+ return (s0, s1, s2)+ inBounds (s0, s1, s2) (i0, i1, i2) = inBounds (s0, s1) (i0, i1) && inBounds s2 i2 + linearSize (s0, s1, s2) = linearSize (s0, s1) * s2+ linearIndex (s0, s1, s2) (i0, i1, i2) = linearIndex (s0, s1) (i0, i1) * s2 + i2+ sizeString s = show s+ indexString i = show i+ indices (s0, s1, s2) = (,,) <$> [0..s0-1] <*> [0..s1-1] <*> [0..s2-1]+ mapToList f (s0, s1, s2) =+ map (\i0 -> + map (\i1 -> + map (\i2 -> f (i0, i1, i2)) + [0..s2-1]) + [0..s1-1]) + [0..s0-1]+instance Dim R4 where+ type Size R4 = (Int, Int, Int, Int)+ type Index R4 = (Int, Int, Int, Int)+ type DimFun R4 a = Int64 -> Int64 -> Int64 -> Int64 -> IO a+ type List R4 a = [[[[a]]]]+ sizeAsArgs df (s0, s1, s2, s3) = df (fromIntegral s0) (fromIntegral s1) (fromIntegral s2) (fromIntegral s3)+ sizeFromPointer p = do+ s0 <- fmap fromIntegral (peekElemOff p 0)+ s1 <- fmap fromIntegral (peekElemOff p 1)+ s2 <- fmap fromIntegral (peekElemOff p 2)+ s3 <- fmap fromIntegral (peekElemOff p 3)+ return (s0, s1, s2, s3)+ inBounds (s0, s1, s2, s3) (i0, i1, i2, i3) = inBounds (s0, s1, s2) (i0, i1, i2) && inBounds s3 i3+ linearSize (s0, s1, s2, s3) = s0 * s1 * s2 * s3+ linearIndex (s0, s1, s2, s3) (i0, i1, i2, i3) = linearIndex (s0, s1, s2) (i0, i1, i2) * s3 + i3+ sizeString s = show s+ indexString i = show i+ indices (s0, s1, s2, s3) = (,,,) <$> [0..s0-1] <*> [0..s1-1] <*> [0..s2-1] <*> [0..s3-1]+ mapToList f (s0, s1, s2, s3) =+ map (\i0 -> ++ map (\i1 -> + map (\i2 ->+ map (\i3 -> f (i0, i1, i2, i3)) + [0..s3-1]) + [0..s2-1]) + [0..s1-1]) + [0..s0-1]+--class (Dim (Rank a)) => Indexable a where+-- type Rank a+-- size :: a -> Size (Rank a)+class (Dim (Rank a)) => Array a where+ type Rank a + type Elem a+ type Mutable a = res | res -> a+ size :: a -> Size (Rank a)+ mutSize :: Mutable a -> Size (Rank a)+ readElem' :: a -> Index (Rank a) -> Elem a + peekElem' :: Mutable a -> Index (Rank a) -> IO (Elem a)+ pokeElem' :: Mutable a -> Index (Rank a) -> Elem a -> IO ()+ copy :: Mutable a -> IO (Mutable a)+ unsafeThaw :: a -> IO (Mutable a)+ unsafeFreeze :: Mutable a -> IO a+ scratch :: Size (Rank a) -> IO (Mutable a)+
+ src/Futhask/Array/Storable.hs view
@@ -0,0 +1,222 @@+{-# LANGUAGE TypeFamilyDependencies, FlexibleContexts, GADTs, FlexibleInstances, TypeOperators #-}++{-|+Storable arrays for primitive values+-}++module Futhask.Array.Storable where+import Futhask.PrimTypes+import Futhask.Array.Element+import Futhask.Array.Boxed+import System.IO.Unsafe+import Foreign.Marshal.Utils (fromBool, toBool)+import qualified Foreign.ForeignPtr as F+import qualified Foreign.Storable as S++data SArray s where+ SArray :: S.Storable s => Int -> F.ForeignPtr s -> SArray s+data MSArray s where+ MSArray :: S.Storable s => Int -> F.ForeignPtr s -> MSArray s++instance Element Int where+ type Array Int = SArray Int+ type MArray Int = MSArray Int+ size = sizeS+ unsafeRead = unsafeReadS+ msize = msizeS+ unsafePeek = unsafePeekS+ unsafePoke = unsafePokeS+ scratch = scratchS+ unsafeThaw = unsafeThawS+ unsafeFreeze = unsafeFreezeS+ unsafeSlice = unsafeSliceS++instance Element F16 where+ type Array F16 = SArray F16+ type MArray F16 = MSArray F16+ size = sizeS+ unsafeRead = unsafeReadS+ msize = msizeS+ unsafePeek = unsafePeekS+ unsafePoke = unsafePokeS+ scratch = scratchS+ unsafeThaw = unsafeThawS+ unsafeFreeze = unsafeFreezeS+ unsafeSlice = unsafeSliceS++instance Element F32 where+ type Array F32 = SArray F32+ type MArray F32 = MSArray F32+ size = sizeS+ unsafeRead = unsafeReadS+ msize = msizeS+ unsafePeek = unsafePeekS+ unsafePoke = unsafePokeS+ scratch = scratchS+ unsafeThaw = unsafeThawS+ unsafeFreeze = unsafeFreezeS+ unsafeSlice = unsafeSliceS++instance Element F64 where+ type Array F64 = SArray F64+ type MArray F64 = MSArray F64+ size = sizeS+ unsafeRead = unsafeReadS+ msize = msizeS+ unsafePeek = unsafePeekS+ unsafePoke = unsafePokeS+ scratch = scratchS+ unsafeThaw = unsafeThawS+ unsafeFreeze = unsafeFreezeS+ unsafeSlice = unsafeSliceS++instance Element I8 where+ type Array I8 = SArray I8+ type MArray I8 = MSArray I8+ size = sizeS+ unsafeRead = unsafeReadS+ msize = msizeS+ unsafePeek = unsafePeekS+ unsafePoke = unsafePokeS+ scratch = scratchS+ unsafeThaw = unsafeThawS+ unsafeFreeze = unsafeFreezeS+ unsafeSlice = unsafeSliceS++instance Element I16 where+ type Array I16 = SArray I16+ type MArray I16 = MSArray I16+ size = sizeS+ unsafeRead = unsafeReadS+ msize = msizeS+ unsafePeek = unsafePeekS+ unsafePoke = unsafePokeS+ scratch = scratchS+ unsafeThaw = unsafeThawS+ unsafeFreeze = unsafeFreezeS+ unsafeSlice = unsafeSliceS++instance Element I32 where+ type Array I32 = SArray I32+ type MArray I32 = MSArray I32+ size = sizeS+ unsafeRead = unsafeReadS+ msize = msizeS+ unsafePeek = unsafePeekS+ unsafePoke = unsafePokeS+ scratch = scratchS+ unsafeThaw = unsafeThawS+ unsafeFreeze = unsafeFreezeS+ unsafeSlice = unsafeSliceS++instance Element I64 where+ type Array I64 = SArray I64+ type MArray I64 = MSArray I64+ size = sizeS+ unsafeRead = unsafeReadS+ msize = msizeS+ unsafePeek = unsafePeekS+ unsafePoke = unsafePokeS+ scratch = scratchS+ unsafeThaw = unsafeThawS+ unsafeFreeze = unsafeFreezeS+ unsafeSlice = unsafeSliceS++instance Element U8 where+ type Array U8 = SArray U8+ type MArray U8 = MSArray U8+ size = sizeS+ unsafeRead = unsafeReadS+ msize = msizeS+ unsafePeek = unsafePeekS+ unsafePoke = unsafePokeS+ scratch = scratchS+ unsafeThaw = unsafeThawS+ unsafeFreeze = unsafeFreezeS+ unsafeSlice = unsafeSliceS++instance Element U16 where+ type Array U16 = SArray U16+ type MArray U16 = MSArray U16+ size = sizeS+ unsafeRead = unsafeReadS+ msize = msizeS+ unsafePeek = unsafePeekS+ unsafePoke = unsafePokeS+ scratch = scratchS+ unsafeThaw = unsafeThawS+ unsafeFreeze = unsafeFreezeS+ unsafeSlice = unsafeSliceS++instance Element U32 where+ type Array U32 = SArray U32+ type MArray U32 = MSArray U32+ size = sizeS+ unsafeRead = unsafeReadS+ msize = msizeS+ unsafePeek = unsafePeekS+ unsafePoke = unsafePokeS+ scratch = scratchS+ unsafeThaw = unsafeThawS+ unsafeFreeze = unsafeFreezeS+ unsafeSlice = unsafeSliceS++instance Element U64 where+ type Array U64 = SArray U64+ type MArray U64 = MSArray U64+ size = sizeS+ unsafeRead = unsafeReadS+ msize = msizeS+ unsafePeek = unsafePeekS+ unsafePoke = unsafePokeS+ scratch = scratchS+ unsafeThaw = unsafeThawS+ unsafeFreeze = unsafeFreezeS+ unsafeSlice = unsafeSliceS++instance Element Bool where+ type Array Bool = SArray CBool+ type MArray Bool = MSArray CBool+ size = sizeS+ unsafeRead a i = toBool $ unsafeReadS a i+ msize = msizeS+ unsafePeek a i = fmap toBool $ unsafePeekS a i+ unsafePoke a i e = unsafePokeS a i $ fromBool e+ scratch = scratchS+ unsafeThaw = unsafeThawS+ unsafeFreeze = unsafeFreezeS+ unsafeSlice = unsafeSliceS++instance Element (SArray elem) where+ type Array (SArray elem) = BArray (SArray elem)+ type MArray (SArray elem) = MBArray (SArray elem)+ size = sizeB+ unsafeRead = unsafeReadB+ msize = msizeB+ unsafePeek = unsafePeekB+ unsafePoke = unsafePokeB+ scratch = scratchB+ unsafeThaw = unsafeThawB+ unsafeFreeze = unsafeFreezeB+ unsafeSlice = unsafeSliceB++instance (Show a, Element a, SArray a ~ Array a) => Show (SArray a) where+ show = show . toList++sizeS :: SArray a -> Int+sizeS (SArray sz _) = sz +unsafeReadS :: S.Storable a => SArray a -> Int -> a+unsafeReadS (SArray _ ptr) idx = unsafePerformIO $ F.withForeignPtr ptr (\ptr -> S.peekElemOff ptr idx)+msizeS :: S.Storable a => MSArray a -> Int+msizeS (MSArray sz _) = sz+unsafePeekS :: MSArray a -> Int -> IO a +unsafePeekS (MSArray _ ptr) idx = F.withForeignPtr ptr (\ptr -> S.peekElemOff ptr idx)+unsafePokeS :: MSArray a -> Int -> a -> IO () +unsafePokeS (MSArray _ ptr) idx elem = F.withForeignPtr ptr (\ptr -> S.pokeElemOff ptr idx elem) +scratchS :: S.Storable a => Int -> IO (MSArray a)+scratchS sz = fmap (MSArray sz) (F.mallocForeignPtrArray sz)+unsafeThawS :: S.Storable a => SArray a -> IO (MSArray a)+unsafeThawS (SArray sz ptr) = pure (MSArray sz ptr)+unsafeFreezeS :: S.Storable a => MSArray a -> IO (SArray a)+unsafeFreezeS (MSArray sz ptr) = pure (SArray sz ptr)+unsafeSliceS (SArray _ ptr) i0 sz = SArray sz (F.plusForeignPtr ptr i0)
+ src/Futhask/Array/Tuple.hs view
@@ -0,0 +1,1328 @@+{-# LANGUAGE TypeFamilyDependencies, FlexibleContexts, GADTs, ApplicativeDo #-}+{-|+Tuple arrays+-}++module Futhask.Array.Tuple where+import Futhask.Array.Element+import Futhask.Array.Boxed+import System.IO.Unsafe++data T2Array a0 a1 where+ T2Array :: (Element a0, Element a1) => Array a0 -> Array a1 -> T2Array a0 a1+data MT2Array a0 a1 where+ MT2Array :: (Element a0, Element a1) => MArray a0 -> MArray a1 -> MT2Array a0 a1+instance (Element a0, Element a1) => Element (a0, a1) where+ type Array (a0, a1) = T2Array a0 a1+ type MArray (a0, a1) = MT2Array a0 a1+ size (T2Array a0 a1) = size a0+ msize (MT2Array a0 a1) = msize a0+ unsafeRead (T2Array a0 a1) idx = (unsafeRead a0 idx, unsafeRead a1 idx)+ unsafePeek (MT2Array a0 a1) idx = do+ e0 <- unsafePeek a0 idx+ e1 <- unsafePeek a1 idx+ pure (e0, e1)+ unsafePoke (MT2Array a0 a1) idx (e0, e1) = do+ unsafePoke a0 idx e0+ unsafePoke a1 idx e1+ unsafeThaw (T2Array a0 a1) = do+ a0' <- unsafeThaw a0+ a1' <- unsafeThaw a1+ pure (MT2Array a0' a1')+ unsafeFreeze (MT2Array a0 a1) = do+ a0' <- unsafeFreeze a0+ a1' <- unsafeFreeze a1+ pure (T2Array a0' a1')+ unsafeSlice (T2Array a0 a1) i s = T2Array (unsafeSlice a0 i s) (unsafeSlice a1 i s)+ scratch s = do+ a0 <- scratch s+ a1 <- scratch s+ pure (MT2Array a0 a1)++instance Element (T2Array a0 a1) where+ type Array (T2Array a0 a1) = BArray (T2Array a0 a1)+ type MArray (T2Array a0 a1) = MBArray (T2Array a0 a1)+ size = sizeB+ msize = msizeB+ unsafeRead = unsafeReadB+ unsafePeek = unsafePeekB+ unsafePoke = unsafePokeB+ unsafeThaw = unsafeThawB+ unsafeFreeze = unsafeFreezeB+ unsafeSlice = unsafeSliceB+ scratch = scratchB++instance (Show a0, Show a1, Element a0, Element a1) => Show (T2Array a0 a1) where+ show = show . toList++zip2 :: (Element a0, Element a1) => Array a0 -> Array a1 -> Array (a0, a1)+zip2 a0 a1 = if size a0 == size a1+ then T2Array a0 a1+ else error "sizes of arguments do not match"+unzip2 :: (Element a0, Element a1) => Array (a0, a1) -> (Array a0, Array a1)+unzip2 (T2Array a0 a1) = (a0, a1)+data T3Array a0 a1 a2 where+ T3Array :: (Element a0, Element a1, Element a2) => Array a0 -> Array a1 -> Array a2 -> T3Array a0 a1 a2+data MT3Array a0 a1 a2 where+ MT3Array :: (Element a0, Element a1, Element a2) => MArray a0 -> MArray a1 -> MArray a2 -> MT3Array a0 a1 a2+instance (Element a0, Element a1, Element a2) => Element (a0, a1, a2) where+ type Array (a0, a1, a2) = T3Array a0 a1 a2+ type MArray (a0, a1, a2) = MT3Array a0 a1 a2+ size (T3Array a0 a1 a2) = size a0+ msize (MT3Array a0 a1 a2) = msize a0+ unsafeRead (T3Array a0 a1 a2) idx = (unsafeRead a0 idx, unsafeRead a1 idx, unsafeRead a2 idx)+ unsafePeek (MT3Array a0 a1 a2) idx = do+ e0 <- unsafePeek a0 idx+ e1 <- unsafePeek a1 idx+ e2 <- unsafePeek a2 idx+ pure (e0, e1, e2)+ unsafePoke (MT3Array a0 a1 a2) idx (e0, e1, e2) = do+ unsafePoke a0 idx e0+ unsafePoke a1 idx e1+ unsafePoke a2 idx e2+ unsafeThaw (T3Array a0 a1 a2) = do+ a0' <- unsafeThaw a0+ a1' <- unsafeThaw a1+ a2' <- unsafeThaw a2+ pure (MT3Array a0' a1' a2')+ unsafeFreeze (MT3Array a0 a1 a2) = do+ a0' <- unsafeFreeze a0+ a1' <- unsafeFreeze a1+ a2' <- unsafeFreeze a2+ pure (T3Array a0' a1' a2')+ unsafeSlice (T3Array a0 a1 a2) i s = T3Array (unsafeSlice a0 i s) (unsafeSlice a1 i s) (unsafeSlice a2 i s)+ scratch s = do+ a0 <- scratch s+ a1 <- scratch s+ a2 <- scratch s+ pure (MT3Array a0 a1 a2)++instance Element (T3Array a0 a1 a2) where+ type Array (T3Array a0 a1 a2) = BArray (T3Array a0 a1 a2)+ type MArray (T3Array a0 a1 a2) = MBArray (T3Array a0 a1 a2)+ size = sizeB+ msize = msizeB+ unsafeRead = unsafeReadB+ unsafePeek = unsafePeekB+ unsafePoke = unsafePokeB+ unsafeThaw = unsafeThawB+ unsafeFreeze = unsafeFreezeB+ unsafeSlice = unsafeSliceB+ scratch = scratchB++instance (Show a0, Show a1, Show a2, Element a0, Element a1, Element a2) => Show (T3Array a0 a1 a2) where+ show = show . toList++zip3 :: (Element a0, Element a1, Element a2) => Array a0 -> Array a1 -> Array a2 -> Array (a0, a1, a2)+zip3 a0 a1 a2 = if size a0 == size a1 && size a1 == size a2+ then T3Array a0 a1 a2+ else error "sizes of arguments do not match"+unzip3 :: (Element a0, Element a1, Element a2) => Array (a0, a1, a2) -> (Array a0, Array a1, Array a2)+unzip3 (T3Array a0 a1 a2) = (a0, a1, a2)+data T4Array a0 a1 a2 a3 where+ T4Array :: (Element a0, Element a1, Element a2, Element a3) => Array a0 -> Array a1 -> Array a2 -> Array a3 -> T4Array a0 a1 a2 a3+data MT4Array a0 a1 a2 a3 where+ MT4Array :: (Element a0, Element a1, Element a2, Element a3) => MArray a0 -> MArray a1 -> MArray a2 -> MArray a3 -> MT4Array a0 a1 a2 a3+instance (Element a0, Element a1, Element a2, Element a3) => Element (a0, a1, a2, a3) where+ type Array (a0, a1, a2, a3) = T4Array a0 a1 a2 a3+ type MArray (a0, a1, a2, a3) = MT4Array a0 a1 a2 a3+ size (T4Array a0 a1 a2 a3) = size a0+ msize (MT4Array a0 a1 a2 a3) = msize a0+ unsafeRead (T4Array a0 a1 a2 a3) idx = (unsafeRead a0 idx, unsafeRead a1 idx, unsafeRead a2 idx, unsafeRead a3 idx)+ unsafePeek (MT4Array a0 a1 a2 a3) idx = do+ e0 <- unsafePeek a0 idx+ e1 <- unsafePeek a1 idx+ e2 <- unsafePeek a2 idx+ e3 <- unsafePeek a3 idx+ pure (e0, e1, e2, e3)+ unsafePoke (MT4Array a0 a1 a2 a3) idx (e0, e1, e2, e3) = do+ unsafePoke a0 idx e0+ unsafePoke a1 idx e1+ unsafePoke a2 idx e2+ unsafePoke a3 idx e3+ unsafeThaw (T4Array a0 a1 a2 a3) = do+ a0' <- unsafeThaw a0+ a1' <- unsafeThaw a1+ a2' <- unsafeThaw a2+ a3' <- unsafeThaw a3+ pure (MT4Array a0' a1' a2' a3')+ unsafeFreeze (MT4Array a0 a1 a2 a3) = do+ a0' <- unsafeFreeze a0+ a1' <- unsafeFreeze a1+ a2' <- unsafeFreeze a2+ a3' <- unsafeFreeze a3+ pure (T4Array a0' a1' a2' a3')+ unsafeSlice (T4Array a0 a1 a2 a3) i s = T4Array (unsafeSlice a0 i s) (unsafeSlice a1 i s) (unsafeSlice a2 i s) (unsafeSlice a3 i s)+ scratch s = do+ a0 <- scratch s+ a1 <- scratch s+ a2 <- scratch s+ a3 <- scratch s+ pure (MT4Array a0 a1 a2 a3)++instance Element (T4Array a0 a1 a2 a3) where+ type Array (T4Array a0 a1 a2 a3) = BArray (T4Array a0 a1 a2 a3)+ type MArray (T4Array a0 a1 a2 a3) = MBArray (T4Array a0 a1 a2 a3)+ size = sizeB+ msize = msizeB+ unsafeRead = unsafeReadB+ unsafePeek = unsafePeekB+ unsafePoke = unsafePokeB+ unsafeThaw = unsafeThawB+ unsafeFreeze = unsafeFreezeB+ unsafeSlice = unsafeSliceB+ scratch = scratchB++instance (Show a0, Show a1, Show a2, Show a3, Element a0, Element a1, Element a2, Element a3) => Show (T4Array a0 a1 a2 a3) where+ show = show . toList++zip4 :: (Element a0, Element a1, Element a2, Element a3) => Array a0 -> Array a1 -> Array a2 -> Array a3 -> Array (a0, a1, a2, a3)+zip4 a0 a1 a2 a3 = if size a0 == size a1 && size a1 == size a2 && size a2 == size a3+ then T4Array a0 a1 a2 a3+ else error "sizes of arguments do not match"+unzip4 :: (Element a0, Element a1, Element a2, Element a3) => Array (a0, a1, a2, a3) -> (Array a0, Array a1, Array a2, Array a3)+unzip4 (T4Array a0 a1 a2 a3) = (a0, a1, a2, a3)+data T5Array a0 a1 a2 a3 a4 where+ T5Array :: (Element a0, Element a1, Element a2, Element a3, Element a4) => Array a0 -> Array a1 -> Array a2 -> Array a3 -> Array a4 -> T5Array a0 a1 a2 a3 a4+data MT5Array a0 a1 a2 a3 a4 where+ MT5Array :: (Element a0, Element a1, Element a2, Element a3, Element a4) => MArray a0 -> MArray a1 -> MArray a2 -> MArray a3 -> MArray a4 -> MT5Array a0 a1 a2 a3 a4+instance (Element a0, Element a1, Element a2, Element a3, Element a4) => Element (a0, a1, a2, a3, a4) where+ type Array (a0, a1, a2, a3, a4) = T5Array a0 a1 a2 a3 a4+ type MArray (a0, a1, a2, a3, a4) = MT5Array a0 a1 a2 a3 a4+ size (T5Array a0 a1 a2 a3 a4) = size a0+ msize (MT5Array a0 a1 a2 a3 a4) = msize a0+ unsafeRead (T5Array a0 a1 a2 a3 a4) idx = (unsafeRead a0 idx, unsafeRead a1 idx, unsafeRead a2 idx, unsafeRead a3 idx, unsafeRead a4 idx)+ unsafePeek (MT5Array a0 a1 a2 a3 a4) idx = do+ e0 <- unsafePeek a0 idx+ e1 <- unsafePeek a1 idx+ e2 <- unsafePeek a2 idx+ e3 <- unsafePeek a3 idx+ e4 <- unsafePeek a4 idx+ pure (e0, e1, e2, e3, e4)+ unsafePoke (MT5Array a0 a1 a2 a3 a4) idx (e0, e1, e2, e3, e4) = do+ unsafePoke a0 idx e0+ unsafePoke a1 idx e1+ unsafePoke a2 idx e2+ unsafePoke a3 idx e3+ unsafePoke a4 idx e4+ unsafeThaw (T5Array a0 a1 a2 a3 a4) = do+ a0' <- unsafeThaw a0+ a1' <- unsafeThaw a1+ a2' <- unsafeThaw a2+ a3' <- unsafeThaw a3+ a4' <- unsafeThaw a4+ pure (MT5Array a0' a1' a2' a3' a4')+ unsafeFreeze (MT5Array a0 a1 a2 a3 a4) = do+ a0' <- unsafeFreeze a0+ a1' <- unsafeFreeze a1+ a2' <- unsafeFreeze a2+ a3' <- unsafeFreeze a3+ a4' <- unsafeFreeze a4+ pure (T5Array a0' a1' a2' a3' a4')+ unsafeSlice (T5Array a0 a1 a2 a3 a4) i s = T5Array (unsafeSlice a0 i s) (unsafeSlice a1 i s) (unsafeSlice a2 i s) (unsafeSlice a3 i s) (unsafeSlice a4 i s)+ scratch s = do+ a0 <- scratch s+ a1 <- scratch s+ a2 <- scratch s+ a3 <- scratch s+ a4 <- scratch s+ pure (MT5Array a0 a1 a2 a3 a4)++instance Element (T5Array a0 a1 a2 a3 a4) where+ type Array (T5Array a0 a1 a2 a3 a4) = BArray (T5Array a0 a1 a2 a3 a4)+ type MArray (T5Array a0 a1 a2 a3 a4) = MBArray (T5Array a0 a1 a2 a3 a4)+ size = sizeB+ msize = msizeB+ unsafeRead = unsafeReadB+ unsafePeek = unsafePeekB+ unsafePoke = unsafePokeB+ unsafeThaw = unsafeThawB+ unsafeFreeze = unsafeFreezeB+ unsafeSlice = unsafeSliceB+ scratch = scratchB++instance (Show a0, Show a1, Show a2, Show a3, Show a4, Element a0, Element a1, Element a2, Element a3, Element a4) => Show (T5Array a0 a1 a2 a3 a4) where+ show = show . toList++zip5 :: (Element a0, Element a1, Element a2, Element a3, Element a4) => Array a0 -> Array a1 -> Array a2 -> Array a3 -> Array a4 -> Array (a0, a1, a2, a3, a4)+zip5 a0 a1 a2 a3 a4 = if size a0 == size a1 && size a1 == size a2 && size a2 == size a3 && size a3 == size a4+ then T5Array a0 a1 a2 a3 a4+ else error "sizes of arguments do not match"+unzip5 :: (Element a0, Element a1, Element a2, Element a3, Element a4) => Array (a0, a1, a2, a3, a4) -> (Array a0, Array a1, Array a2, Array a3, Array a4)+unzip5 (T5Array a0 a1 a2 a3 a4) = (a0, a1, a2, a3, a4)+data T6Array a0 a1 a2 a3 a4 a5 where+ T6Array :: (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5) => Array a0 -> Array a1 -> Array a2 -> Array a3 -> Array a4 -> Array a5 -> T6Array a0 a1 a2 a3 a4 a5+data MT6Array a0 a1 a2 a3 a4 a5 where+ MT6Array :: (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5) => MArray a0 -> MArray a1 -> MArray a2 -> MArray a3 -> MArray a4 -> MArray a5 -> MT6Array a0 a1 a2 a3 a4 a5+instance (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5) => Element (a0, a1, a2, a3, a4, a5) where+ type Array (a0, a1, a2, a3, a4, a5) = T6Array a0 a1 a2 a3 a4 a5+ type MArray (a0, a1, a2, a3, a4, a5) = MT6Array a0 a1 a2 a3 a4 a5+ size (T6Array a0 a1 a2 a3 a4 a5) = size a0+ msize (MT6Array a0 a1 a2 a3 a4 a5) = msize a0+ unsafeRead (T6Array a0 a1 a2 a3 a4 a5) idx = (unsafeRead a0 idx, unsafeRead a1 idx, unsafeRead a2 idx, unsafeRead a3 idx, unsafeRead a4 idx, unsafeRead a5 idx)+ unsafePeek (MT6Array a0 a1 a2 a3 a4 a5) idx = do+ e0 <- unsafePeek a0 idx+ e1 <- unsafePeek a1 idx+ e2 <- unsafePeek a2 idx+ e3 <- unsafePeek a3 idx+ e4 <- unsafePeek a4 idx+ e5 <- unsafePeek a5 idx+ pure (e0, e1, e2, e3, e4, e5)+ unsafePoke (MT6Array a0 a1 a2 a3 a4 a5) idx (e0, e1, e2, e3, e4, e5) = do+ unsafePoke a0 idx e0+ unsafePoke a1 idx e1+ unsafePoke a2 idx e2+ unsafePoke a3 idx e3+ unsafePoke a4 idx e4+ unsafePoke a5 idx e5+ unsafeThaw (T6Array a0 a1 a2 a3 a4 a5) = do+ a0' <- unsafeThaw a0+ a1' <- unsafeThaw a1+ a2' <- unsafeThaw a2+ a3' <- unsafeThaw a3+ a4' <- unsafeThaw a4+ a5' <- unsafeThaw a5+ pure (MT6Array a0' a1' a2' a3' a4' a5')+ unsafeFreeze (MT6Array a0 a1 a2 a3 a4 a5) = do+ a0' <- unsafeFreeze a0+ a1' <- unsafeFreeze a1+ a2' <- unsafeFreeze a2+ a3' <- unsafeFreeze a3+ a4' <- unsafeFreeze a4+ a5' <- unsafeFreeze a5+ pure (T6Array a0' a1' a2' a3' a4' a5')+ unsafeSlice (T6Array a0 a1 a2 a3 a4 a5) i s = T6Array (unsafeSlice a0 i s) (unsafeSlice a1 i s) (unsafeSlice a2 i s) (unsafeSlice a3 i s) (unsafeSlice a4 i s) (unsafeSlice a5 i s)+ scratch s = do+ a0 <- scratch s+ a1 <- scratch s+ a2 <- scratch s+ a3 <- scratch s+ a4 <- scratch s+ a5 <- scratch s+ pure (MT6Array a0 a1 a2 a3 a4 a5)++instance Element (T6Array a0 a1 a2 a3 a4 a5) where+ type Array (T6Array a0 a1 a2 a3 a4 a5) = BArray (T6Array a0 a1 a2 a3 a4 a5)+ type MArray (T6Array a0 a1 a2 a3 a4 a5) = MBArray (T6Array a0 a1 a2 a3 a4 a5)+ size = sizeB+ msize = msizeB+ unsafeRead = unsafeReadB+ unsafePeek = unsafePeekB+ unsafePoke = unsafePokeB+ unsafeThaw = unsafeThawB+ unsafeFreeze = unsafeFreezeB+ unsafeSlice = unsafeSliceB+ scratch = scratchB++instance (Show a0, Show a1, Show a2, Show a3, Show a4, Show a5, Element a0, Element a1, Element a2, Element a3, Element a4, Element a5) => Show (T6Array a0 a1 a2 a3 a4 a5) where+ show = show . toList++zip6 :: (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5) => Array a0 -> Array a1 -> Array a2 -> Array a3 -> Array a4 -> Array a5 -> Array (a0, a1, a2, a3, a4, a5)+zip6 a0 a1 a2 a3 a4 a5 = if size a0 == size a1 && size a1 == size a2 && size a2 == size a3 && size a3 == size a4 && size a4 == size a5+ then T6Array a0 a1 a2 a3 a4 a5+ else error "sizes of arguments do not match"+unzip6 :: (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5) => Array (a0, a1, a2, a3, a4, a5) -> (Array a0, Array a1, Array a2, Array a3, Array a4, Array a5)+unzip6 (T6Array a0 a1 a2 a3 a4 a5) = (a0, a1, a2, a3, a4, a5)+data T7Array a0 a1 a2 a3 a4 a5 a6 where+ T7Array :: (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6) => Array a0 -> Array a1 -> Array a2 -> Array a3 -> Array a4 -> Array a5 -> Array a6 -> T7Array a0 a1 a2 a3 a4 a5 a6+data MT7Array a0 a1 a2 a3 a4 a5 a6 where+ MT7Array :: (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6) => MArray a0 -> MArray a1 -> MArray a2 -> MArray a3 -> MArray a4 -> MArray a5 -> MArray a6 -> MT7Array a0 a1 a2 a3 a4 a5 a6+instance (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6) => Element (a0, a1, a2, a3, a4, a5, a6) where+ type Array (a0, a1, a2, a3, a4, a5, a6) = T7Array a0 a1 a2 a3 a4 a5 a6+ type MArray (a0, a1, a2, a3, a4, a5, a6) = MT7Array a0 a1 a2 a3 a4 a5 a6+ size (T7Array a0 a1 a2 a3 a4 a5 a6) = size a0+ msize (MT7Array a0 a1 a2 a3 a4 a5 a6) = msize a0+ unsafeRead (T7Array a0 a1 a2 a3 a4 a5 a6) idx = (unsafeRead a0 idx, unsafeRead a1 idx, unsafeRead a2 idx, unsafeRead a3 idx, unsafeRead a4 idx, unsafeRead a5 idx, unsafeRead a6 idx)+ unsafePeek (MT7Array a0 a1 a2 a3 a4 a5 a6) idx = do+ e0 <- unsafePeek a0 idx+ e1 <- unsafePeek a1 idx+ e2 <- unsafePeek a2 idx+ e3 <- unsafePeek a3 idx+ e4 <- unsafePeek a4 idx+ e5 <- unsafePeek a5 idx+ e6 <- unsafePeek a6 idx+ pure (e0, e1, e2, e3, e4, e5, e6)+ unsafePoke (MT7Array a0 a1 a2 a3 a4 a5 a6) idx (e0, e1, e2, e3, e4, e5, e6) = do+ unsafePoke a0 idx e0+ unsafePoke a1 idx e1+ unsafePoke a2 idx e2+ unsafePoke a3 idx e3+ unsafePoke a4 idx e4+ unsafePoke a5 idx e5+ unsafePoke a6 idx e6+ unsafeThaw (T7Array a0 a1 a2 a3 a4 a5 a6) = do+ a0' <- unsafeThaw a0+ a1' <- unsafeThaw a1+ a2' <- unsafeThaw a2+ a3' <- unsafeThaw a3+ a4' <- unsafeThaw a4+ a5' <- unsafeThaw a5+ a6' <- unsafeThaw a6+ pure (MT7Array a0' a1' a2' a3' a4' a5' a6')+ unsafeFreeze (MT7Array a0 a1 a2 a3 a4 a5 a6) = do+ a0' <- unsafeFreeze a0+ a1' <- unsafeFreeze a1+ a2' <- unsafeFreeze a2+ a3' <- unsafeFreeze a3+ a4' <- unsafeFreeze a4+ a5' <- unsafeFreeze a5+ a6' <- unsafeFreeze a6+ pure (T7Array a0' a1' a2' a3' a4' a5' a6')+ unsafeSlice (T7Array a0 a1 a2 a3 a4 a5 a6) i s = T7Array (unsafeSlice a0 i s) (unsafeSlice a1 i s) (unsafeSlice a2 i s) (unsafeSlice a3 i s) (unsafeSlice a4 i s) (unsafeSlice a5 i s) (unsafeSlice a6 i s)+ scratch s = do+ a0 <- scratch s+ a1 <- scratch s+ a2 <- scratch s+ a3 <- scratch s+ a4 <- scratch s+ a5 <- scratch s+ a6 <- scratch s+ pure (MT7Array a0 a1 a2 a3 a4 a5 a6)++instance Element (T7Array a0 a1 a2 a3 a4 a5 a6) where+ type Array (T7Array a0 a1 a2 a3 a4 a5 a6) = BArray (T7Array a0 a1 a2 a3 a4 a5 a6)+ type MArray (T7Array a0 a1 a2 a3 a4 a5 a6) = MBArray (T7Array a0 a1 a2 a3 a4 a5 a6)+ size = sizeB+ msize = msizeB+ unsafeRead = unsafeReadB+ unsafePeek = unsafePeekB+ unsafePoke = unsafePokeB+ unsafeThaw = unsafeThawB+ unsafeFreeze = unsafeFreezeB+ unsafeSlice = unsafeSliceB+ scratch = scratchB++instance (Show a0, Show a1, Show a2, Show a3, Show a4, Show a5, Show a6, Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6) => Show (T7Array a0 a1 a2 a3 a4 a5 a6) where+ show = show . toList++zip7 :: (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6) => Array a0 -> Array a1 -> Array a2 -> Array a3 -> Array a4 -> Array a5 -> Array a6 -> Array (a0, a1, a2, a3, a4, a5, a6)+zip7 a0 a1 a2 a3 a4 a5 a6 = if size a0 == size a1 && size a1 == size a2 && size a2 == size a3 && size a3 == size a4 && size a4 == size a5 && size a5 == size a6+ then T7Array a0 a1 a2 a3 a4 a5 a6+ else error "sizes of arguments do not match"+unzip7 :: (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6) => Array (a0, a1, a2, a3, a4, a5, a6) -> (Array a0, Array a1, Array a2, Array a3, Array a4, Array a5, Array a6)+unzip7 (T7Array a0 a1 a2 a3 a4 a5 a6) = (a0, a1, a2, a3, a4, a5, a6)+data T8Array a0 a1 a2 a3 a4 a5 a6 a7 where+ T8Array :: (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7) => Array a0 -> Array a1 -> Array a2 -> Array a3 -> Array a4 -> Array a5 -> Array a6 -> Array a7 -> T8Array a0 a1 a2 a3 a4 a5 a6 a7+data MT8Array a0 a1 a2 a3 a4 a5 a6 a7 where+ MT8Array :: (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7) => MArray a0 -> MArray a1 -> MArray a2 -> MArray a3 -> MArray a4 -> MArray a5 -> MArray a6 -> MArray a7 -> MT8Array a0 a1 a2 a3 a4 a5 a6 a7+instance (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7) => Element (a0, a1, a2, a3, a4, a5, a6, a7) where+ type Array (a0, a1, a2, a3, a4, a5, a6, a7) = T8Array a0 a1 a2 a3 a4 a5 a6 a7+ type MArray (a0, a1, a2, a3, a4, a5, a6, a7) = MT8Array a0 a1 a2 a3 a4 a5 a6 a7+ size (T8Array a0 a1 a2 a3 a4 a5 a6 a7) = size a0+ msize (MT8Array a0 a1 a2 a3 a4 a5 a6 a7) = msize a0+ unsafeRead (T8Array a0 a1 a2 a3 a4 a5 a6 a7) idx = (unsafeRead a0 idx, unsafeRead a1 idx, unsafeRead a2 idx, unsafeRead a3 idx, unsafeRead a4 idx, unsafeRead a5 idx, unsafeRead a6 idx, unsafeRead a7 idx)+ unsafePeek (MT8Array a0 a1 a2 a3 a4 a5 a6 a7) idx = do+ e0 <- unsafePeek a0 idx+ e1 <- unsafePeek a1 idx+ e2 <- unsafePeek a2 idx+ e3 <- unsafePeek a3 idx+ e4 <- unsafePeek a4 idx+ e5 <- unsafePeek a5 idx+ e6 <- unsafePeek a6 idx+ e7 <- unsafePeek a7 idx+ pure (e0, e1, e2, e3, e4, e5, e6, e7)+ unsafePoke (MT8Array a0 a1 a2 a3 a4 a5 a6 a7) idx (e0, e1, e2, e3, e4, e5, e6, e7) = do+ unsafePoke a0 idx e0+ unsafePoke a1 idx e1+ unsafePoke a2 idx e2+ unsafePoke a3 idx e3+ unsafePoke a4 idx e4+ unsafePoke a5 idx e5+ unsafePoke a6 idx e6+ unsafePoke a7 idx e7+ unsafeThaw (T8Array a0 a1 a2 a3 a4 a5 a6 a7) = do+ a0' <- unsafeThaw a0+ a1' <- unsafeThaw a1+ a2' <- unsafeThaw a2+ a3' <- unsafeThaw a3+ a4' <- unsafeThaw a4+ a5' <- unsafeThaw a5+ a6' <- unsafeThaw a6+ a7' <- unsafeThaw a7+ pure (MT8Array a0' a1' a2' a3' a4' a5' a6' a7')+ unsafeFreeze (MT8Array a0 a1 a2 a3 a4 a5 a6 a7) = do+ a0' <- unsafeFreeze a0+ a1' <- unsafeFreeze a1+ a2' <- unsafeFreeze a2+ a3' <- unsafeFreeze a3+ a4' <- unsafeFreeze a4+ a5' <- unsafeFreeze a5+ a6' <- unsafeFreeze a6+ a7' <- unsafeFreeze a7+ pure (T8Array a0' a1' a2' a3' a4' a5' a6' a7')+ unsafeSlice (T8Array a0 a1 a2 a3 a4 a5 a6 a7) i s = T8Array (unsafeSlice a0 i s) (unsafeSlice a1 i s) (unsafeSlice a2 i s) (unsafeSlice a3 i s) (unsafeSlice a4 i s) (unsafeSlice a5 i s) (unsafeSlice a6 i s) (unsafeSlice a7 i s)+ scratch s = do+ a0 <- scratch s+ a1 <- scratch s+ a2 <- scratch s+ a3 <- scratch s+ a4 <- scratch s+ a5 <- scratch s+ a6 <- scratch s+ a7 <- scratch s+ pure (MT8Array a0 a1 a2 a3 a4 a5 a6 a7)++instance Element (T8Array a0 a1 a2 a3 a4 a5 a6 a7) where+ type Array (T8Array a0 a1 a2 a3 a4 a5 a6 a7) = BArray (T8Array a0 a1 a2 a3 a4 a5 a6 a7)+ type MArray (T8Array a0 a1 a2 a3 a4 a5 a6 a7) = MBArray (T8Array a0 a1 a2 a3 a4 a5 a6 a7)+ size = sizeB+ msize = msizeB+ unsafeRead = unsafeReadB+ unsafePeek = unsafePeekB+ unsafePoke = unsafePokeB+ unsafeThaw = unsafeThawB+ unsafeFreeze = unsafeFreezeB+ unsafeSlice = unsafeSliceB+ scratch = scratchB++instance (Show a0, Show a1, Show a2, Show a3, Show a4, Show a5, Show a6, Show a7, Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7) => Show (T8Array a0 a1 a2 a3 a4 a5 a6 a7) where+ show = show . toList++zip8 :: (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7) => Array a0 -> Array a1 -> Array a2 -> Array a3 -> Array a4 -> Array a5 -> Array a6 -> Array a7 -> Array (a0, a1, a2, a3, a4, a5, a6, a7)+zip8 a0 a1 a2 a3 a4 a5 a6 a7 = if size a0 == size a1 && size a1 == size a2 && size a2 == size a3 && size a3 == size a4 && size a4 == size a5 && size a5 == size a6 && size a6 == size a7+ then T8Array a0 a1 a2 a3 a4 a5 a6 a7+ else error "sizes of arguments do not match"+unzip8 :: (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7) => Array (a0, a1, a2, a3, a4, a5, a6, a7) -> (Array a0, Array a1, Array a2, Array a3, Array a4, Array a5, Array a6, Array a7)+unzip8 (T8Array a0 a1 a2 a3 a4 a5 a6 a7) = (a0, a1, a2, a3, a4, a5, a6, a7)+data T9Array a0 a1 a2 a3 a4 a5 a6 a7 a8 where+ T9Array :: (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8) => Array a0 -> Array a1 -> Array a2 -> Array a3 -> Array a4 -> Array a5 -> Array a6 -> Array a7 -> Array a8 -> T9Array a0 a1 a2 a3 a4 a5 a6 a7 a8+data MT9Array a0 a1 a2 a3 a4 a5 a6 a7 a8 where+ MT9Array :: (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8) => MArray a0 -> MArray a1 -> MArray a2 -> MArray a3 -> MArray a4 -> MArray a5 -> MArray a6 -> MArray a7 -> MArray a8 -> MT9Array a0 a1 a2 a3 a4 a5 a6 a7 a8+instance (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8) => Element (a0, a1, a2, a3, a4, a5, a6, a7, a8) where+ type Array (a0, a1, a2, a3, a4, a5, a6, a7, a8) = T9Array a0 a1 a2 a3 a4 a5 a6 a7 a8+ type MArray (a0, a1, a2, a3, a4, a5, a6, a7, a8) = MT9Array a0 a1 a2 a3 a4 a5 a6 a7 a8+ size (T9Array a0 a1 a2 a3 a4 a5 a6 a7 a8) = size a0+ msize (MT9Array a0 a1 a2 a3 a4 a5 a6 a7 a8) = msize a0+ unsafeRead (T9Array a0 a1 a2 a3 a4 a5 a6 a7 a8) idx = (unsafeRead a0 idx, unsafeRead a1 idx, unsafeRead a2 idx, unsafeRead a3 idx, unsafeRead a4 idx, unsafeRead a5 idx, unsafeRead a6 idx, unsafeRead a7 idx, unsafeRead a8 idx)+ unsafePeek (MT9Array a0 a1 a2 a3 a4 a5 a6 a7 a8) idx = do+ e0 <- unsafePeek a0 idx+ e1 <- unsafePeek a1 idx+ e2 <- unsafePeek a2 idx+ e3 <- unsafePeek a3 idx+ e4 <- unsafePeek a4 idx+ e5 <- unsafePeek a5 idx+ e6 <- unsafePeek a6 idx+ e7 <- unsafePeek a7 idx+ e8 <- unsafePeek a8 idx+ pure (e0, e1, e2, e3, e4, e5, e6, e7, e8)+ unsafePoke (MT9Array a0 a1 a2 a3 a4 a5 a6 a7 a8) idx (e0, e1, e2, e3, e4, e5, e6, e7, e8) = do+ unsafePoke a0 idx e0+ unsafePoke a1 idx e1+ unsafePoke a2 idx e2+ unsafePoke a3 idx e3+ unsafePoke a4 idx e4+ unsafePoke a5 idx e5+ unsafePoke a6 idx e6+ unsafePoke a7 idx e7+ unsafePoke a8 idx e8+ unsafeThaw (T9Array a0 a1 a2 a3 a4 a5 a6 a7 a8) = do+ a0' <- unsafeThaw a0+ a1' <- unsafeThaw a1+ a2' <- unsafeThaw a2+ a3' <- unsafeThaw a3+ a4' <- unsafeThaw a4+ a5' <- unsafeThaw a5+ a6' <- unsafeThaw a6+ a7' <- unsafeThaw a7+ a8' <- unsafeThaw a8+ pure (MT9Array a0' a1' a2' a3' a4' a5' a6' a7' a8')+ unsafeFreeze (MT9Array a0 a1 a2 a3 a4 a5 a6 a7 a8) = do+ a0' <- unsafeFreeze a0+ a1' <- unsafeFreeze a1+ a2' <- unsafeFreeze a2+ a3' <- unsafeFreeze a3+ a4' <- unsafeFreeze a4+ a5' <- unsafeFreeze a5+ a6' <- unsafeFreeze a6+ a7' <- unsafeFreeze a7+ a8' <- unsafeFreeze a8+ pure (T9Array a0' a1' a2' a3' a4' a5' a6' a7' a8')+ unsafeSlice (T9Array a0 a1 a2 a3 a4 a5 a6 a7 a8) i s = T9Array (unsafeSlice a0 i s) (unsafeSlice a1 i s) (unsafeSlice a2 i s) (unsafeSlice a3 i s) (unsafeSlice a4 i s) (unsafeSlice a5 i s) (unsafeSlice a6 i s) (unsafeSlice a7 i s) (unsafeSlice a8 i s)+ scratch s = do+ a0 <- scratch s+ a1 <- scratch s+ a2 <- scratch s+ a3 <- scratch s+ a4 <- scratch s+ a5 <- scratch s+ a6 <- scratch s+ a7 <- scratch s+ a8 <- scratch s+ pure (MT9Array a0 a1 a2 a3 a4 a5 a6 a7 a8)++instance Element (T9Array a0 a1 a2 a3 a4 a5 a6 a7 a8) where+ type Array (T9Array a0 a1 a2 a3 a4 a5 a6 a7 a8) = BArray (T9Array a0 a1 a2 a3 a4 a5 a6 a7 a8)+ type MArray (T9Array a0 a1 a2 a3 a4 a5 a6 a7 a8) = MBArray (T9Array a0 a1 a2 a3 a4 a5 a6 a7 a8)+ size = sizeB+ msize = msizeB+ unsafeRead = unsafeReadB+ unsafePeek = unsafePeekB+ unsafePoke = unsafePokeB+ unsafeThaw = unsafeThawB+ unsafeFreeze = unsafeFreezeB+ unsafeSlice = unsafeSliceB+ scratch = scratchB++instance (Show a0, Show a1, Show a2, Show a3, Show a4, Show a5, Show a6, Show a7, Show a8, Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8) => Show (T9Array a0 a1 a2 a3 a4 a5 a6 a7 a8) where+ show = show . toList++zip9 :: (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8) => Array a0 -> Array a1 -> Array a2 -> Array a3 -> Array a4 -> Array a5 -> Array a6 -> Array a7 -> Array a8 -> Array (a0, a1, a2, a3, a4, a5, a6, a7, a8)+zip9 a0 a1 a2 a3 a4 a5 a6 a7 a8 = if size a0 == size a1 && size a1 == size a2 && size a2 == size a3 && size a3 == size a4 && size a4 == size a5 && size a5 == size a6 && size a6 == size a7 && size a7 == size a8+ then T9Array a0 a1 a2 a3 a4 a5 a6 a7 a8+ else error "sizes of arguments do not match"+unzip9 :: (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8) => Array (a0, a1, a2, a3, a4, a5, a6, a7, a8) -> (Array a0, Array a1, Array a2, Array a3, Array a4, Array a5, Array a6, Array a7, Array a8)+unzip9 (T9Array a0 a1 a2 a3 a4 a5 a6 a7 a8) = (a0, a1, a2, a3, a4, a5, a6, a7, a8)+data T10Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 where+ T10Array :: (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8, Element a9) => Array a0 -> Array a1 -> Array a2 -> Array a3 -> Array a4 -> Array a5 -> Array a6 -> Array a7 -> Array a8 -> Array a9 -> T10Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9+data MT10Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 where+ MT10Array :: (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8, Element a9) => MArray a0 -> MArray a1 -> MArray a2 -> MArray a3 -> MArray a4 -> MArray a5 -> MArray a6 -> MArray a7 -> MArray a8 -> MArray a9 -> MT10Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9+instance (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8, Element a9) => Element (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) where+ type Array (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) = T10Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9+ type MArray (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) = MT10Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9+ size (T10Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9) = size a0+ msize (MT10Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9) = msize a0+ unsafeRead (T10Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9) idx = (unsafeRead a0 idx, unsafeRead a1 idx, unsafeRead a2 idx, unsafeRead a3 idx, unsafeRead a4 idx, unsafeRead a5 idx, unsafeRead a6 idx, unsafeRead a7 idx, unsafeRead a8 idx, unsafeRead a9 idx)+ unsafePeek (MT10Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9) idx = do+ e0 <- unsafePeek a0 idx+ e1 <- unsafePeek a1 idx+ e2 <- unsafePeek a2 idx+ e3 <- unsafePeek a3 idx+ e4 <- unsafePeek a4 idx+ e5 <- unsafePeek a5 idx+ e6 <- unsafePeek a6 idx+ e7 <- unsafePeek a7 idx+ e8 <- unsafePeek a8 idx+ e9 <- unsafePeek a9 idx+ pure (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9)+ unsafePoke (MT10Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9) idx (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9) = do+ unsafePoke a0 idx e0+ unsafePoke a1 idx e1+ unsafePoke a2 idx e2+ unsafePoke a3 idx e3+ unsafePoke a4 idx e4+ unsafePoke a5 idx e5+ unsafePoke a6 idx e6+ unsafePoke a7 idx e7+ unsafePoke a8 idx e8+ unsafePoke a9 idx e9+ unsafeThaw (T10Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9) = do+ a0' <- unsafeThaw a0+ a1' <- unsafeThaw a1+ a2' <- unsafeThaw a2+ a3' <- unsafeThaw a3+ a4' <- unsafeThaw a4+ a5' <- unsafeThaw a5+ a6' <- unsafeThaw a6+ a7' <- unsafeThaw a7+ a8' <- unsafeThaw a8+ a9' <- unsafeThaw a9+ pure (MT10Array a0' a1' a2' a3' a4' a5' a6' a7' a8' a9')+ unsafeFreeze (MT10Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9) = do+ a0' <- unsafeFreeze a0+ a1' <- unsafeFreeze a1+ a2' <- unsafeFreeze a2+ a3' <- unsafeFreeze a3+ a4' <- unsafeFreeze a4+ a5' <- unsafeFreeze a5+ a6' <- unsafeFreeze a6+ a7' <- unsafeFreeze a7+ a8' <- unsafeFreeze a8+ a9' <- unsafeFreeze a9+ pure (T10Array a0' a1' a2' a3' a4' a5' a6' a7' a8' a9')+ unsafeSlice (T10Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9) i s = T10Array (unsafeSlice a0 i s) (unsafeSlice a1 i s) (unsafeSlice a2 i s) (unsafeSlice a3 i s) (unsafeSlice a4 i s) (unsafeSlice a5 i s) (unsafeSlice a6 i s) (unsafeSlice a7 i s) (unsafeSlice a8 i s) (unsafeSlice a9 i s)+ scratch s = do+ a0 <- scratch s+ a1 <- scratch s+ a2 <- scratch s+ a3 <- scratch s+ a4 <- scratch s+ a5 <- scratch s+ a6 <- scratch s+ a7 <- scratch s+ a8 <- scratch s+ a9 <- scratch s+ pure (MT10Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9)++instance Element (T10Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9) where+ type Array (T10Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9) = BArray (T10Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9)+ type MArray (T10Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9) = MBArray (T10Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9)+ size = sizeB+ msize = msizeB+ unsafeRead = unsafeReadB+ unsafePeek = unsafePeekB+ unsafePoke = unsafePokeB+ unsafeThaw = unsafeThawB+ unsafeFreeze = unsafeFreezeB+ unsafeSlice = unsafeSliceB+ scratch = scratchB++instance (Show a0, Show a1, Show a2, Show a3, Show a4, Show a5, Show a6, Show a7, Show a8, Show a9, Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8, Element a9) => Show (T10Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9) where+ show = show . toList++zip10 :: (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8, Element a9) => Array a0 -> Array a1 -> Array a2 -> Array a3 -> Array a4 -> Array a5 -> Array a6 -> Array a7 -> Array a8 -> Array a9 -> Array (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)+zip10 a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 = if size a0 == size a1 && size a1 == size a2 && size a2 == size a3 && size a3 == size a4 && size a4 == size a5 && size a5 == size a6 && size a6 == size a7 && size a7 == size a8 && size a8 == size a9+ then T10Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9+ else error "sizes of arguments do not match"+unzip10 :: (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8, Element a9) => Array (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) -> (Array a0, Array a1, Array a2, Array a3, Array a4, Array a5, Array a6, Array a7, Array a8, Array a9)+unzip10 (T10Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9) = (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)+data T11Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 where+ T11Array :: (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8, Element a9, Element a10) => Array a0 -> Array a1 -> Array a2 -> Array a3 -> Array a4 -> Array a5 -> Array a6 -> Array a7 -> Array a8 -> Array a9 -> Array a10 -> T11Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10+data MT11Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 where+ MT11Array :: (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8, Element a9, Element a10) => MArray a0 -> MArray a1 -> MArray a2 -> MArray a3 -> MArray a4 -> MArray a5 -> MArray a6 -> MArray a7 -> MArray a8 -> MArray a9 -> MArray a10 -> MT11Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10+instance (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8, Element a9, Element a10) => Element (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) where+ type Array (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) = T11Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10+ type MArray (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) = MT11Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10+ size (T11Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10) = size a0+ msize (MT11Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10) = msize a0+ unsafeRead (T11Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10) idx = (unsafeRead a0 idx, unsafeRead a1 idx, unsafeRead a2 idx, unsafeRead a3 idx, unsafeRead a4 idx, unsafeRead a5 idx, unsafeRead a6 idx, unsafeRead a7 idx, unsafeRead a8 idx, unsafeRead a9 idx, unsafeRead a10 idx)+ unsafePeek (MT11Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10) idx = do+ e0 <- unsafePeek a0 idx+ e1 <- unsafePeek a1 idx+ e2 <- unsafePeek a2 idx+ e3 <- unsafePeek a3 idx+ e4 <- unsafePeek a4 idx+ e5 <- unsafePeek a5 idx+ e6 <- unsafePeek a6 idx+ e7 <- unsafePeek a7 idx+ e8 <- unsafePeek a8 idx+ e9 <- unsafePeek a9 idx+ e10 <- unsafePeek a10 idx+ pure (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10)+ unsafePoke (MT11Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10) idx (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10) = do+ unsafePoke a0 idx e0+ unsafePoke a1 idx e1+ unsafePoke a2 idx e2+ unsafePoke a3 idx e3+ unsafePoke a4 idx e4+ unsafePoke a5 idx e5+ unsafePoke a6 idx e6+ unsafePoke a7 idx e7+ unsafePoke a8 idx e8+ unsafePoke a9 idx e9+ unsafePoke a10 idx e10+ unsafeThaw (T11Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10) = do+ a0' <- unsafeThaw a0+ a1' <- unsafeThaw a1+ a2' <- unsafeThaw a2+ a3' <- unsafeThaw a3+ a4' <- unsafeThaw a4+ a5' <- unsafeThaw a5+ a6' <- unsafeThaw a6+ a7' <- unsafeThaw a7+ a8' <- unsafeThaw a8+ a9' <- unsafeThaw a9+ a10' <- unsafeThaw a10+ pure (MT11Array a0' a1' a2' a3' a4' a5' a6' a7' a8' a9' a10')+ unsafeFreeze (MT11Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10) = do+ a0' <- unsafeFreeze a0+ a1' <- unsafeFreeze a1+ a2' <- unsafeFreeze a2+ a3' <- unsafeFreeze a3+ a4' <- unsafeFreeze a4+ a5' <- unsafeFreeze a5+ a6' <- unsafeFreeze a6+ a7' <- unsafeFreeze a7+ a8' <- unsafeFreeze a8+ a9' <- unsafeFreeze a9+ a10' <- unsafeFreeze a10+ pure (T11Array a0' a1' a2' a3' a4' a5' a6' a7' a8' a9' a10')+ unsafeSlice (T11Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10) i s = T11Array (unsafeSlice a0 i s) (unsafeSlice a1 i s) (unsafeSlice a2 i s) (unsafeSlice a3 i s) (unsafeSlice a4 i s) (unsafeSlice a5 i s) (unsafeSlice a6 i s) (unsafeSlice a7 i s) (unsafeSlice a8 i s) (unsafeSlice a9 i s) (unsafeSlice a10 i s)+ scratch s = do+ a0 <- scratch s+ a1 <- scratch s+ a2 <- scratch s+ a3 <- scratch s+ a4 <- scratch s+ a5 <- scratch s+ a6 <- scratch s+ a7 <- scratch s+ a8 <- scratch s+ a9 <- scratch s+ a10 <- scratch s+ pure (MT11Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10)++instance Element (T11Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10) where+ type Array (T11Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10) = BArray (T11Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10)+ type MArray (T11Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10) = MBArray (T11Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10)+ size = sizeB+ msize = msizeB+ unsafeRead = unsafeReadB+ unsafePeek = unsafePeekB+ unsafePoke = unsafePokeB+ unsafeThaw = unsafeThawB+ unsafeFreeze = unsafeFreezeB+ unsafeSlice = unsafeSliceB+ scratch = scratchB++instance (Show a0, Show a1, Show a2, Show a3, Show a4, Show a5, Show a6, Show a7, Show a8, Show a9, Show a10, Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8, Element a9, Element a10) => Show (T11Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10) where+ show = show . toList++zip11 :: (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8, Element a9, Element a10) => Array a0 -> Array a1 -> Array a2 -> Array a3 -> Array a4 -> Array a5 -> Array a6 -> Array a7 -> Array a8 -> Array a9 -> Array a10 -> Array (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)+zip11 a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 = if size a0 == size a1 && size a1 == size a2 && size a2 == size a3 && size a3 == size a4 && size a4 == size a5 && size a5 == size a6 && size a6 == size a7 && size a7 == size a8 && size a8 == size a9 && size a9 == size a10+ then T11Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10+ else error "sizes of arguments do not match"+unzip11 :: (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8, Element a9, Element a10) => Array (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) -> (Array a0, Array a1, Array a2, Array a3, Array a4, Array a5, Array a6, Array a7, Array a8, Array a9, Array a10)+unzip11 (T11Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10) = (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)+data T12Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 where+ T12Array :: (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8, Element a9, Element a10, Element a11) => Array a0 -> Array a1 -> Array a2 -> Array a3 -> Array a4 -> Array a5 -> Array a6 -> Array a7 -> Array a8 -> Array a9 -> Array a10 -> Array a11 -> T12Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11+data MT12Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 where+ MT12Array :: (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8, Element a9, Element a10, Element a11) => MArray a0 -> MArray a1 -> MArray a2 -> MArray a3 -> MArray a4 -> MArray a5 -> MArray a6 -> MArray a7 -> MArray a8 -> MArray a9 -> MArray a10 -> MArray a11 -> MT12Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11+instance (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8, Element a9, Element a10, Element a11) => Element (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) where+ type Array (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) = T12Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11+ type MArray (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) = MT12Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11+ size (T12Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11) = size a0+ msize (MT12Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11) = msize a0+ unsafeRead (T12Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11) idx = (unsafeRead a0 idx, unsafeRead a1 idx, unsafeRead a2 idx, unsafeRead a3 idx, unsafeRead a4 idx, unsafeRead a5 idx, unsafeRead a6 idx, unsafeRead a7 idx, unsafeRead a8 idx, unsafeRead a9 idx, unsafeRead a10 idx, unsafeRead a11 idx)+ unsafePeek (MT12Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11) idx = do+ e0 <- unsafePeek a0 idx+ e1 <- unsafePeek a1 idx+ e2 <- unsafePeek a2 idx+ e3 <- unsafePeek a3 idx+ e4 <- unsafePeek a4 idx+ e5 <- unsafePeek a5 idx+ e6 <- unsafePeek a6 idx+ e7 <- unsafePeek a7 idx+ e8 <- unsafePeek a8 idx+ e9 <- unsafePeek a9 idx+ e10 <- unsafePeek a10 idx+ e11 <- unsafePeek a11 idx+ pure (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11)+ unsafePoke (MT12Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11) idx (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11) = do+ unsafePoke a0 idx e0+ unsafePoke a1 idx e1+ unsafePoke a2 idx e2+ unsafePoke a3 idx e3+ unsafePoke a4 idx e4+ unsafePoke a5 idx e5+ unsafePoke a6 idx e6+ unsafePoke a7 idx e7+ unsafePoke a8 idx e8+ unsafePoke a9 idx e9+ unsafePoke a10 idx e10+ unsafePoke a11 idx e11+ unsafeThaw (T12Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11) = do+ a0' <- unsafeThaw a0+ a1' <- unsafeThaw a1+ a2' <- unsafeThaw a2+ a3' <- unsafeThaw a3+ a4' <- unsafeThaw a4+ a5' <- unsafeThaw a5+ a6' <- unsafeThaw a6+ a7' <- unsafeThaw a7+ a8' <- unsafeThaw a8+ a9' <- unsafeThaw a9+ a10' <- unsafeThaw a10+ a11' <- unsafeThaw a11+ pure (MT12Array a0' a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11')+ unsafeFreeze (MT12Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11) = do+ a0' <- unsafeFreeze a0+ a1' <- unsafeFreeze a1+ a2' <- unsafeFreeze a2+ a3' <- unsafeFreeze a3+ a4' <- unsafeFreeze a4+ a5' <- unsafeFreeze a5+ a6' <- unsafeFreeze a6+ a7' <- unsafeFreeze a7+ a8' <- unsafeFreeze a8+ a9' <- unsafeFreeze a9+ a10' <- unsafeFreeze a10+ a11' <- unsafeFreeze a11+ pure (T12Array a0' a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11')+ unsafeSlice (T12Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11) i s = T12Array (unsafeSlice a0 i s) (unsafeSlice a1 i s) (unsafeSlice a2 i s) (unsafeSlice a3 i s) (unsafeSlice a4 i s) (unsafeSlice a5 i s) (unsafeSlice a6 i s) (unsafeSlice a7 i s) (unsafeSlice a8 i s) (unsafeSlice a9 i s) (unsafeSlice a10 i s) (unsafeSlice a11 i s)+ scratch s = do+ a0 <- scratch s+ a1 <- scratch s+ a2 <- scratch s+ a3 <- scratch s+ a4 <- scratch s+ a5 <- scratch s+ a6 <- scratch s+ a7 <- scratch s+ a8 <- scratch s+ a9 <- scratch s+ a10 <- scratch s+ a11 <- scratch s+ pure (MT12Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11)++instance Element (T12Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11) where+ type Array (T12Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11) = BArray (T12Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11)+ type MArray (T12Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11) = MBArray (T12Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11)+ size = sizeB+ msize = msizeB+ unsafeRead = unsafeReadB+ unsafePeek = unsafePeekB+ unsafePoke = unsafePokeB+ unsafeThaw = unsafeThawB+ unsafeFreeze = unsafeFreezeB+ unsafeSlice = unsafeSliceB+ scratch = scratchB++instance (Show a0, Show a1, Show a2, Show a3, Show a4, Show a5, Show a6, Show a7, Show a8, Show a9, Show a10, Show a11, Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8, Element a9, Element a10, Element a11) => Show (T12Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11) where+ show = show . toList++zip12 :: (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8, Element a9, Element a10, Element a11) => Array a0 -> Array a1 -> Array a2 -> Array a3 -> Array a4 -> Array a5 -> Array a6 -> Array a7 -> Array a8 -> Array a9 -> Array a10 -> Array a11 -> Array (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11)+zip12 a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 = if size a0 == size a1 && size a1 == size a2 && size a2 == size a3 && size a3 == size a4 && size a4 == size a5 && size a5 == size a6 && size a6 == size a7 && size a7 == size a8 && size a8 == size a9 && size a9 == size a10 && size a10 == size a11+ then T12Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11+ else error "sizes of arguments do not match"+unzip12 :: (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8, Element a9, Element a10, Element a11) => Array (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) -> (Array a0, Array a1, Array a2, Array a3, Array a4, Array a5, Array a6, Array a7, Array a8, Array a9, Array a10, Array a11)+unzip12 (T12Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11) = (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11)+data T13Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 where+ T13Array :: (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8, Element a9, Element a10, Element a11, Element a12) => Array a0 -> Array a1 -> Array a2 -> Array a3 -> Array a4 -> Array a5 -> Array a6 -> Array a7 -> Array a8 -> Array a9 -> Array a10 -> Array a11 -> Array a12 -> T13Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12+data MT13Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 where+ MT13Array :: (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8, Element a9, Element a10, Element a11, Element a12) => MArray a0 -> MArray a1 -> MArray a2 -> MArray a3 -> MArray a4 -> MArray a5 -> MArray a6 -> MArray a7 -> MArray a8 -> MArray a9 -> MArray a10 -> MArray a11 -> MArray a12 -> MT13Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12+instance (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8, Element a9, Element a10, Element a11, Element a12) => Element (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) where+ type Array (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) = T13Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12+ type MArray (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) = MT13Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12+ size (T13Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12) = size a0+ msize (MT13Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12) = msize a0+ unsafeRead (T13Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12) idx = (unsafeRead a0 idx, unsafeRead a1 idx, unsafeRead a2 idx, unsafeRead a3 idx, unsafeRead a4 idx, unsafeRead a5 idx, unsafeRead a6 idx, unsafeRead a7 idx, unsafeRead a8 idx, unsafeRead a9 idx, unsafeRead a10 idx, unsafeRead a11 idx, unsafeRead a12 idx)+ unsafePeek (MT13Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12) idx = do+ e0 <- unsafePeek a0 idx+ e1 <- unsafePeek a1 idx+ e2 <- unsafePeek a2 idx+ e3 <- unsafePeek a3 idx+ e4 <- unsafePeek a4 idx+ e5 <- unsafePeek a5 idx+ e6 <- unsafePeek a6 idx+ e7 <- unsafePeek a7 idx+ e8 <- unsafePeek a8 idx+ e9 <- unsafePeek a9 idx+ e10 <- unsafePeek a10 idx+ e11 <- unsafePeek a11 idx+ e12 <- unsafePeek a12 idx+ pure (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12)+ unsafePoke (MT13Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12) idx (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12) = do+ unsafePoke a0 idx e0+ unsafePoke a1 idx e1+ unsafePoke a2 idx e2+ unsafePoke a3 idx e3+ unsafePoke a4 idx e4+ unsafePoke a5 idx e5+ unsafePoke a6 idx e6+ unsafePoke a7 idx e7+ unsafePoke a8 idx e8+ unsafePoke a9 idx e9+ unsafePoke a10 idx e10+ unsafePoke a11 idx e11+ unsafePoke a12 idx e12+ unsafeThaw (T13Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12) = do+ a0' <- unsafeThaw a0+ a1' <- unsafeThaw a1+ a2' <- unsafeThaw a2+ a3' <- unsafeThaw a3+ a4' <- unsafeThaw a4+ a5' <- unsafeThaw a5+ a6' <- unsafeThaw a6+ a7' <- unsafeThaw a7+ a8' <- unsafeThaw a8+ a9' <- unsafeThaw a9+ a10' <- unsafeThaw a10+ a11' <- unsafeThaw a11+ a12' <- unsafeThaw a12+ pure (MT13Array a0' a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12')+ unsafeFreeze (MT13Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12) = do+ a0' <- unsafeFreeze a0+ a1' <- unsafeFreeze a1+ a2' <- unsafeFreeze a2+ a3' <- unsafeFreeze a3+ a4' <- unsafeFreeze a4+ a5' <- unsafeFreeze a5+ a6' <- unsafeFreeze a6+ a7' <- unsafeFreeze a7+ a8' <- unsafeFreeze a8+ a9' <- unsafeFreeze a9+ a10' <- unsafeFreeze a10+ a11' <- unsafeFreeze a11+ a12' <- unsafeFreeze a12+ pure (T13Array a0' a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12')+ unsafeSlice (T13Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12) i s = T13Array (unsafeSlice a0 i s) (unsafeSlice a1 i s) (unsafeSlice a2 i s) (unsafeSlice a3 i s) (unsafeSlice a4 i s) (unsafeSlice a5 i s) (unsafeSlice a6 i s) (unsafeSlice a7 i s) (unsafeSlice a8 i s) (unsafeSlice a9 i s) (unsafeSlice a10 i s) (unsafeSlice a11 i s) (unsafeSlice a12 i s)+ scratch s = do+ a0 <- scratch s+ a1 <- scratch s+ a2 <- scratch s+ a3 <- scratch s+ a4 <- scratch s+ a5 <- scratch s+ a6 <- scratch s+ a7 <- scratch s+ a8 <- scratch s+ a9 <- scratch s+ a10 <- scratch s+ a11 <- scratch s+ a12 <- scratch s+ pure (MT13Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12)++instance Element (T13Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12) where+ type Array (T13Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12) = BArray (T13Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12)+ type MArray (T13Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12) = MBArray (T13Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12)+ size = sizeB+ msize = msizeB+ unsafeRead = unsafeReadB+ unsafePeek = unsafePeekB+ unsafePoke = unsafePokeB+ unsafeThaw = unsafeThawB+ unsafeFreeze = unsafeFreezeB+ unsafeSlice = unsafeSliceB+ scratch = scratchB++instance (Show a0, Show a1, Show a2, Show a3, Show a4, Show a5, Show a6, Show a7, Show a8, Show a9, Show a10, Show a11, Show a12, Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8, Element a9, Element a10, Element a11, Element a12) => Show (T13Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12) where+ show = show . toList++zip13 :: (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8, Element a9, Element a10, Element a11, Element a12) => Array a0 -> Array a1 -> Array a2 -> Array a3 -> Array a4 -> Array a5 -> Array a6 -> Array a7 -> Array a8 -> Array a9 -> Array a10 -> Array a11 -> Array a12 -> Array (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12)+zip13 a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 = if size a0 == size a1 && size a1 == size a2 && size a2 == size a3 && size a3 == size a4 && size a4 == size a5 && size a5 == size a6 && size a6 == size a7 && size a7 == size a8 && size a8 == size a9 && size a9 == size a10 && size a10 == size a11 && size a11 == size a12+ then T13Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12+ else error "sizes of arguments do not match"+unzip13 :: (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8, Element a9, Element a10, Element a11, Element a12) => Array (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) -> (Array a0, Array a1, Array a2, Array a3, Array a4, Array a5, Array a6, Array a7, Array a8, Array a9, Array a10, Array a11, Array a12)+unzip13 (T13Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12) = (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12)+data T14Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 where+ T14Array :: (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8, Element a9, Element a10, Element a11, Element a12, Element a13) => Array a0 -> Array a1 -> Array a2 -> Array a3 -> Array a4 -> Array a5 -> Array a6 -> Array a7 -> Array a8 -> Array a9 -> Array a10 -> Array a11 -> Array a12 -> Array a13 -> T14Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13+data MT14Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 where+ MT14Array :: (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8, Element a9, Element a10, Element a11, Element a12, Element a13) => MArray a0 -> MArray a1 -> MArray a2 -> MArray a3 -> MArray a4 -> MArray a5 -> MArray a6 -> MArray a7 -> MArray a8 -> MArray a9 -> MArray a10 -> MArray a11 -> MArray a12 -> MArray a13 -> MT14Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13+instance (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8, Element a9, Element a10, Element a11, Element a12, Element a13) => Element (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) where+ type Array (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) = T14Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13+ type MArray (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) = MT14Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13+ size (T14Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13) = size a0+ msize (MT14Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13) = msize a0+ unsafeRead (T14Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13) idx = (unsafeRead a0 idx, unsafeRead a1 idx, unsafeRead a2 idx, unsafeRead a3 idx, unsafeRead a4 idx, unsafeRead a5 idx, unsafeRead a6 idx, unsafeRead a7 idx, unsafeRead a8 idx, unsafeRead a9 idx, unsafeRead a10 idx, unsafeRead a11 idx, unsafeRead a12 idx, unsafeRead a13 idx)+ unsafePeek (MT14Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13) idx = do+ e0 <- unsafePeek a0 idx+ e1 <- unsafePeek a1 idx+ e2 <- unsafePeek a2 idx+ e3 <- unsafePeek a3 idx+ e4 <- unsafePeek a4 idx+ e5 <- unsafePeek a5 idx+ e6 <- unsafePeek a6 idx+ e7 <- unsafePeek a7 idx+ e8 <- unsafePeek a8 idx+ e9 <- unsafePeek a9 idx+ e10 <- unsafePeek a10 idx+ e11 <- unsafePeek a11 idx+ e12 <- unsafePeek a12 idx+ e13 <- unsafePeek a13 idx+ pure (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13)+ unsafePoke (MT14Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13) idx (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13) = do+ unsafePoke a0 idx e0+ unsafePoke a1 idx e1+ unsafePoke a2 idx e2+ unsafePoke a3 idx e3+ unsafePoke a4 idx e4+ unsafePoke a5 idx e5+ unsafePoke a6 idx e6+ unsafePoke a7 idx e7+ unsafePoke a8 idx e8+ unsafePoke a9 idx e9+ unsafePoke a10 idx e10+ unsafePoke a11 idx e11+ unsafePoke a12 idx e12+ unsafePoke a13 idx e13+ unsafeThaw (T14Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13) = do+ a0' <- unsafeThaw a0+ a1' <- unsafeThaw a1+ a2' <- unsafeThaw a2+ a3' <- unsafeThaw a3+ a4' <- unsafeThaw a4+ a5' <- unsafeThaw a5+ a6' <- unsafeThaw a6+ a7' <- unsafeThaw a7+ a8' <- unsafeThaw a8+ a9' <- unsafeThaw a9+ a10' <- unsafeThaw a10+ a11' <- unsafeThaw a11+ a12' <- unsafeThaw a12+ a13' <- unsafeThaw a13+ pure (MT14Array a0' a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' a13')+ unsafeFreeze (MT14Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13) = do+ a0' <- unsafeFreeze a0+ a1' <- unsafeFreeze a1+ a2' <- unsafeFreeze a2+ a3' <- unsafeFreeze a3+ a4' <- unsafeFreeze a4+ a5' <- unsafeFreeze a5+ a6' <- unsafeFreeze a6+ a7' <- unsafeFreeze a7+ a8' <- unsafeFreeze a8+ a9' <- unsafeFreeze a9+ a10' <- unsafeFreeze a10+ a11' <- unsafeFreeze a11+ a12' <- unsafeFreeze a12+ a13' <- unsafeFreeze a13+ pure (T14Array a0' a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' a13')+ unsafeSlice (T14Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13) i s = T14Array (unsafeSlice a0 i s) (unsafeSlice a1 i s) (unsafeSlice a2 i s) (unsafeSlice a3 i s) (unsafeSlice a4 i s) (unsafeSlice a5 i s) (unsafeSlice a6 i s) (unsafeSlice a7 i s) (unsafeSlice a8 i s) (unsafeSlice a9 i s) (unsafeSlice a10 i s) (unsafeSlice a11 i s) (unsafeSlice a12 i s) (unsafeSlice a13 i s)+ scratch s = do+ a0 <- scratch s+ a1 <- scratch s+ a2 <- scratch s+ a3 <- scratch s+ a4 <- scratch s+ a5 <- scratch s+ a6 <- scratch s+ a7 <- scratch s+ a8 <- scratch s+ a9 <- scratch s+ a10 <- scratch s+ a11 <- scratch s+ a12 <- scratch s+ a13 <- scratch s+ pure (MT14Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13)++instance Element (T14Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13) where+ type Array (T14Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13) = BArray (T14Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13)+ type MArray (T14Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13) = MBArray (T14Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13)+ size = sizeB+ msize = msizeB+ unsafeRead = unsafeReadB+ unsafePeek = unsafePeekB+ unsafePoke = unsafePokeB+ unsafeThaw = unsafeThawB+ unsafeFreeze = unsafeFreezeB+ unsafeSlice = unsafeSliceB+ scratch = scratchB++instance (Show a0, Show a1, Show a2, Show a3, Show a4, Show a5, Show a6, Show a7, Show a8, Show a9, Show a10, Show a11, Show a12, Show a13, Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8, Element a9, Element a10, Element a11, Element a12, Element a13) => Show (T14Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13) where+ show = show . toList++zip14 :: (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8, Element a9, Element a10, Element a11, Element a12, Element a13) => Array a0 -> Array a1 -> Array a2 -> Array a3 -> Array a4 -> Array a5 -> Array a6 -> Array a7 -> Array a8 -> Array a9 -> Array a10 -> Array a11 -> Array a12 -> Array a13 -> Array (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13)+zip14 a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 = if size a0 == size a1 && size a1 == size a2 && size a2 == size a3 && size a3 == size a4 && size a4 == size a5 && size a5 == size a6 && size a6 == size a7 && size a7 == size a8 && size a8 == size a9 && size a9 == size a10 && size a10 == size a11 && size a11 == size a12 && size a12 == size a13+ then T14Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13+ else error "sizes of arguments do not match"+unzip14 :: (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8, Element a9, Element a10, Element a11, Element a12, Element a13) => Array (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) -> (Array a0, Array a1, Array a2, Array a3, Array a4, Array a5, Array a6, Array a7, Array a8, Array a9, Array a10, Array a11, Array a12, Array a13)+unzip14 (T14Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13) = (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13)+data T15Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 where+ T15Array :: (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8, Element a9, Element a10, Element a11, Element a12, Element a13, Element a14) => Array a0 -> Array a1 -> Array a2 -> Array a3 -> Array a4 -> Array a5 -> Array a6 -> Array a7 -> Array a8 -> Array a9 -> Array a10 -> Array a11 -> Array a12 -> Array a13 -> Array a14 -> T15Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14+data MT15Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 where+ MT15Array :: (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8, Element a9, Element a10, Element a11, Element a12, Element a13, Element a14) => MArray a0 -> MArray a1 -> MArray a2 -> MArray a3 -> MArray a4 -> MArray a5 -> MArray a6 -> MArray a7 -> MArray a8 -> MArray a9 -> MArray a10 -> MArray a11 -> MArray a12 -> MArray a13 -> MArray a14 -> MT15Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14+instance (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8, Element a9, Element a10, Element a11, Element a12, Element a13, Element a14) => Element (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) where+ type Array (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) = T15Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14+ type MArray (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) = MT15Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14+ size (T15Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14) = size a0+ msize (MT15Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14) = msize a0+ unsafeRead (T15Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14) idx = (unsafeRead a0 idx, unsafeRead a1 idx, unsafeRead a2 idx, unsafeRead a3 idx, unsafeRead a4 idx, unsafeRead a5 idx, unsafeRead a6 idx, unsafeRead a7 idx, unsafeRead a8 idx, unsafeRead a9 idx, unsafeRead a10 idx, unsafeRead a11 idx, unsafeRead a12 idx, unsafeRead a13 idx, unsafeRead a14 idx)+ unsafePeek (MT15Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14) idx = do+ e0 <- unsafePeek a0 idx+ e1 <- unsafePeek a1 idx+ e2 <- unsafePeek a2 idx+ e3 <- unsafePeek a3 idx+ e4 <- unsafePeek a4 idx+ e5 <- unsafePeek a5 idx+ e6 <- unsafePeek a6 idx+ e7 <- unsafePeek a7 idx+ e8 <- unsafePeek a8 idx+ e9 <- unsafePeek a9 idx+ e10 <- unsafePeek a10 idx+ e11 <- unsafePeek a11 idx+ e12 <- unsafePeek a12 idx+ e13 <- unsafePeek a13 idx+ e14 <- unsafePeek a14 idx+ pure (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14)+ unsafePoke (MT15Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14) idx (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14) = do+ unsafePoke a0 idx e0+ unsafePoke a1 idx e1+ unsafePoke a2 idx e2+ unsafePoke a3 idx e3+ unsafePoke a4 idx e4+ unsafePoke a5 idx e5+ unsafePoke a6 idx e6+ unsafePoke a7 idx e7+ unsafePoke a8 idx e8+ unsafePoke a9 idx e9+ unsafePoke a10 idx e10+ unsafePoke a11 idx e11+ unsafePoke a12 idx e12+ unsafePoke a13 idx e13+ unsafePoke a14 idx e14+ unsafeThaw (T15Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14) = do+ a0' <- unsafeThaw a0+ a1' <- unsafeThaw a1+ a2' <- unsafeThaw a2+ a3' <- unsafeThaw a3+ a4' <- unsafeThaw a4+ a5' <- unsafeThaw a5+ a6' <- unsafeThaw a6+ a7' <- unsafeThaw a7+ a8' <- unsafeThaw a8+ a9' <- unsafeThaw a9+ a10' <- unsafeThaw a10+ a11' <- unsafeThaw a11+ a12' <- unsafeThaw a12+ a13' <- unsafeThaw a13+ a14' <- unsafeThaw a14+ pure (MT15Array a0' a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' a13' a14')+ unsafeFreeze (MT15Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14) = do+ a0' <- unsafeFreeze a0+ a1' <- unsafeFreeze a1+ a2' <- unsafeFreeze a2+ a3' <- unsafeFreeze a3+ a4' <- unsafeFreeze a4+ a5' <- unsafeFreeze a5+ a6' <- unsafeFreeze a6+ a7' <- unsafeFreeze a7+ a8' <- unsafeFreeze a8+ a9' <- unsafeFreeze a9+ a10' <- unsafeFreeze a10+ a11' <- unsafeFreeze a11+ a12' <- unsafeFreeze a12+ a13' <- unsafeFreeze a13+ a14' <- unsafeFreeze a14+ pure (T15Array a0' a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' a13' a14')+ unsafeSlice (T15Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14) i s = T15Array (unsafeSlice a0 i s) (unsafeSlice a1 i s) (unsafeSlice a2 i s) (unsafeSlice a3 i s) (unsafeSlice a4 i s) (unsafeSlice a5 i s) (unsafeSlice a6 i s) (unsafeSlice a7 i s) (unsafeSlice a8 i s) (unsafeSlice a9 i s) (unsafeSlice a10 i s) (unsafeSlice a11 i s) (unsafeSlice a12 i s) (unsafeSlice a13 i s) (unsafeSlice a14 i s)+ scratch s = do+ a0 <- scratch s+ a1 <- scratch s+ a2 <- scratch s+ a3 <- scratch s+ a4 <- scratch s+ a5 <- scratch s+ a6 <- scratch s+ a7 <- scratch s+ a8 <- scratch s+ a9 <- scratch s+ a10 <- scratch s+ a11 <- scratch s+ a12 <- scratch s+ a13 <- scratch s+ a14 <- scratch s+ pure (MT15Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14)++instance Element (T15Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14) where+ type Array (T15Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14) = BArray (T15Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14)+ type MArray (T15Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14) = MBArray (T15Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14)+ size = sizeB+ msize = msizeB+ unsafeRead = unsafeReadB+ unsafePeek = unsafePeekB+ unsafePoke = unsafePokeB+ unsafeThaw = unsafeThawB+ unsafeFreeze = unsafeFreezeB+ unsafeSlice = unsafeSliceB+ scratch = scratchB++instance (Show a0, Show a1, Show a2, Show a3, Show a4, Show a5, Show a6, Show a7, Show a8, Show a9, Show a10, Show a11, Show a12, Show a13, Show a14, Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8, Element a9, Element a10, Element a11, Element a12, Element a13, Element a14) => Show (T15Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14) where+ show = show . toList++zip15 :: (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8, Element a9, Element a10, Element a11, Element a12, Element a13, Element a14) => Array a0 -> Array a1 -> Array a2 -> Array a3 -> Array a4 -> Array a5 -> Array a6 -> Array a7 -> Array a8 -> Array a9 -> Array a10 -> Array a11 -> Array a12 -> Array a13 -> Array a14 -> Array (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14)+zip15 a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 = if size a0 == size a1 && size a1 == size a2 && size a2 == size a3 && size a3 == size a4 && size a4 == size a5 && size a5 == size a6 && size a6 == size a7 && size a7 == size a8 && size a8 == size a9 && size a9 == size a10 && size a10 == size a11 && size a11 == size a12 && size a12 == size a13 && size a13 == size a14+ then T15Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14+ else error "sizes of arguments do not match"+unzip15 :: (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8, Element a9, Element a10, Element a11, Element a12, Element a13, Element a14) => Array (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) -> (Array a0, Array a1, Array a2, Array a3, Array a4, Array a5, Array a6, Array a7, Array a8, Array a9, Array a10, Array a11, Array a12, Array a13, Array a14)+unzip15 (T15Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14) = (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14)+data T16Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 where+ T16Array :: (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8, Element a9, Element a10, Element a11, Element a12, Element a13, Element a14, Element a15) => Array a0 -> Array a1 -> Array a2 -> Array a3 -> Array a4 -> Array a5 -> Array a6 -> Array a7 -> Array a8 -> Array a9 -> Array a10 -> Array a11 -> Array a12 -> Array a13 -> Array a14 -> Array a15 -> T16Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15+data MT16Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 where+ MT16Array :: (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8, Element a9, Element a10, Element a11, Element a12, Element a13, Element a14, Element a15) => MArray a0 -> MArray a1 -> MArray a2 -> MArray a3 -> MArray a4 -> MArray a5 -> MArray a6 -> MArray a7 -> MArray a8 -> MArray a9 -> MArray a10 -> MArray a11 -> MArray a12 -> MArray a13 -> MArray a14 -> MArray a15 -> MT16Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15+instance (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8, Element a9, Element a10, Element a11, Element a12, Element a13, Element a14, Element a15) => Element (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) where+ type Array (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) = T16Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15+ type MArray (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) = MT16Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15+ size (T16Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15) = size a0+ msize (MT16Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15) = msize a0+ unsafeRead (T16Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15) idx = (unsafeRead a0 idx, unsafeRead a1 idx, unsafeRead a2 idx, unsafeRead a3 idx, unsafeRead a4 idx, unsafeRead a5 idx, unsafeRead a6 idx, unsafeRead a7 idx, unsafeRead a8 idx, unsafeRead a9 idx, unsafeRead a10 idx, unsafeRead a11 idx, unsafeRead a12 idx, unsafeRead a13 idx, unsafeRead a14 idx, unsafeRead a15 idx)+ unsafePeek (MT16Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15) idx = do+ e0 <- unsafePeek a0 idx+ e1 <- unsafePeek a1 idx+ e2 <- unsafePeek a2 idx+ e3 <- unsafePeek a3 idx+ e4 <- unsafePeek a4 idx+ e5 <- unsafePeek a5 idx+ e6 <- unsafePeek a6 idx+ e7 <- unsafePeek a7 idx+ e8 <- unsafePeek a8 idx+ e9 <- unsafePeek a9 idx+ e10 <- unsafePeek a10 idx+ e11 <- unsafePeek a11 idx+ e12 <- unsafePeek a12 idx+ e13 <- unsafePeek a13 idx+ e14 <- unsafePeek a14 idx+ e15 <- unsafePeek a15 idx+ pure (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15)+ unsafePoke (MT16Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15) idx (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15) = do+ unsafePoke a0 idx e0+ unsafePoke a1 idx e1+ unsafePoke a2 idx e2+ unsafePoke a3 idx e3+ unsafePoke a4 idx e4+ unsafePoke a5 idx e5+ unsafePoke a6 idx e6+ unsafePoke a7 idx e7+ unsafePoke a8 idx e8+ unsafePoke a9 idx e9+ unsafePoke a10 idx e10+ unsafePoke a11 idx e11+ unsafePoke a12 idx e12+ unsafePoke a13 idx e13+ unsafePoke a14 idx e14+ unsafePoke a15 idx e15+ unsafeThaw (T16Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15) = do+ a0' <- unsafeThaw a0+ a1' <- unsafeThaw a1+ a2' <- unsafeThaw a2+ a3' <- unsafeThaw a3+ a4' <- unsafeThaw a4+ a5' <- unsafeThaw a5+ a6' <- unsafeThaw a6+ a7' <- unsafeThaw a7+ a8' <- unsafeThaw a8+ a9' <- unsafeThaw a9+ a10' <- unsafeThaw a10+ a11' <- unsafeThaw a11+ a12' <- unsafeThaw a12+ a13' <- unsafeThaw a13+ a14' <- unsafeThaw a14+ a15' <- unsafeThaw a15+ pure (MT16Array a0' a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' a13' a14' a15')+ unsafeFreeze (MT16Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15) = do+ a0' <- unsafeFreeze a0+ a1' <- unsafeFreeze a1+ a2' <- unsafeFreeze a2+ a3' <- unsafeFreeze a3+ a4' <- unsafeFreeze a4+ a5' <- unsafeFreeze a5+ a6' <- unsafeFreeze a6+ a7' <- unsafeFreeze a7+ a8' <- unsafeFreeze a8+ a9' <- unsafeFreeze a9+ a10' <- unsafeFreeze a10+ a11' <- unsafeFreeze a11+ a12' <- unsafeFreeze a12+ a13' <- unsafeFreeze a13+ a14' <- unsafeFreeze a14+ a15' <- unsafeFreeze a15+ pure (T16Array a0' a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' a13' a14' a15')+ unsafeSlice (T16Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15) i s = T16Array (unsafeSlice a0 i s) (unsafeSlice a1 i s) (unsafeSlice a2 i s) (unsafeSlice a3 i s) (unsafeSlice a4 i s) (unsafeSlice a5 i s) (unsafeSlice a6 i s) (unsafeSlice a7 i s) (unsafeSlice a8 i s) (unsafeSlice a9 i s) (unsafeSlice a10 i s) (unsafeSlice a11 i s) (unsafeSlice a12 i s) (unsafeSlice a13 i s) (unsafeSlice a14 i s) (unsafeSlice a15 i s)+ scratch s = do+ a0 <- scratch s+ a1 <- scratch s+ a2 <- scratch s+ a3 <- scratch s+ a4 <- scratch s+ a5 <- scratch s+ a6 <- scratch s+ a7 <- scratch s+ a8 <- scratch s+ a9 <- scratch s+ a10 <- scratch s+ a11 <- scratch s+ a12 <- scratch s+ a13 <- scratch s+ a14 <- scratch s+ a15 <- scratch s+ pure (MT16Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15)++instance Element (T16Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15) where+ type Array (T16Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15) = BArray (T16Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15)+ type MArray (T16Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15) = MBArray (T16Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15)+ size = sizeB+ msize = msizeB+ unsafeRead = unsafeReadB+ unsafePeek = unsafePeekB+ unsafePoke = unsafePokeB+ unsafeThaw = unsafeThawB+ unsafeFreeze = unsafeFreezeB+ unsafeSlice = unsafeSliceB+ scratch = scratchB+++zip16 :: (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8, Element a9, Element a10, Element a11, Element a12, Element a13, Element a14, Element a15) => Array a0 -> Array a1 -> Array a2 -> Array a3 -> Array a4 -> Array a5 -> Array a6 -> Array a7 -> Array a8 -> Array a9 -> Array a10 -> Array a11 -> Array a12 -> Array a13 -> Array a14 -> Array a15 -> Array (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)+zip16 a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 = if size a0 == size a1 && size a1 == size a2 && size a2 == size a3 && size a3 == size a4 && size a4 == size a5 && size a5 == size a6 && size a6 == size a7 && size a7 == size a8 && size a8 == size a9 && size a9 == size a10 && size a10 == size a11 && size a11 == size a12 && size a12 == size a13 && size a13 == size a14 && size a14 == size a15+ then T16Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15+ else error "sizes of arguments do not match"+unzip16 :: (Element a0, Element a1, Element a2, Element a3, Element a4, Element a5, Element a6, Element a7, Element a8, Element a9, Element a10, Element a11, Element a12, Element a13, Element a14, Element a15) => Array (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) -> (Array a0, Array a1, Array a2, Array a3, Array a4, Array a5, Array a6, Array a7, Array a8, Array a9, Array a10, Array a11, Array a12, Array a13, Array a14, Array a15)+unzip16 (T16Array a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15) = (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)
+ src/Futhask/Array/Unit.hs view
@@ -0,0 +1,36 @@+{-# LANGUAGE TypeFamilyDependencies, FlexibleContexts, GADTs, FlexibleInstances #-}+{-|+Unit Array+-}+module Futhask.Array.Unit where+import Futhask.Array.Element+import Futhask.Array.Boxed++data UnitArray = UnitArray Int+data MUnitArray = MUnitArray Int++instance Element () where+ type Array () = UnitArray+ type MArray () = MUnitArray+ size (UnitArray sz) = sz+ msize (MUnitArray sz) = sz+ unsafeRead _ _ = ()+ unsafePeek _ _ = pure ()+ unsafePoke _ _ _ = pure ()+ unsafeThaw (UnitArray sz) = pure $ MUnitArray sz+ unsafeFreeze (MUnitArray sz) = pure $ UnitArray sz+ unsafeSlice _ _ sz = UnitArray sz+ scratch sz = pure $ MUnitArray sz++instance Element UnitArray where+ type Array UnitArray = BArray UnitArray+ type MArray UnitArray = MBArray UnitArray+ size = sizeB+ msize = msizeB+ unsafeRead = unsafeReadB+ unsafePeek = unsafePeekB+ unsafePoke = unsafePokeB+ unsafeThaw = unsafeThawB+ unsafeFreeze = unsafeFreezeB+ unsafeSlice = unsafeSliceB+ scratch = scratchB
+ src/Futhask/Context.hs view
@@ -0,0 +1,206 @@+{-# LANGUAGE RankNTypes, ExistentialQuantification, FlexibleInstances, UndecidableInstances, TypeFamilyDependencies, MultiParamTypeClasses, ScopedTypeVariables, FlexibleContexts, AllowAmbiguousTypes #-}+{-|+Defines context options and utilities used internally.+Mostly useful for creating new abstractions from the @Raw@ interface. +-}++module Futhask.Context where+import Data.Word+import Data.Int+import Foreign.C+import Foreign.C.String+import Foreign.Ptr+import Foreign.Storable+import Foreign.ForeignPtr (ForeignPtr, withForeignPtr)+import Foreign.Concurrent+import Foreign.Marshal.Alloc+import Foreign.Marshal.Array as A+import Control.Monad+import Control.Concurrent+import Control.Concurrent.MVar+import System.Mem++-- *Reference Counting+type ReferenceCounter = MVar Int++newRefCounter :: IO ReferenceCounter+newRefCounter = newMVar 0++increment :: ReferenceCounter -> IO ()+increment c = modifyMVar_ c (\a -> return $! (a+1))++decrement :: ReferenceCounter -> IO ()+decrement c = modifyMVar_ c (\a -> return $! (a-1))++isZero :: ReferenceCounter -> IO Bool+isZero c = readMVar c >>= \a -> return (a==0) ++waitForZero :: ReferenceCounter -> IO ()+waitForZero c = isZero c >>= \b -> if b then return () else yield >> waitForZero c+newForeignPtrWithRef refCounter pointer finalizer + = increment refCounter >> newForeignPtr pointer (finalizer >> decrement refCounter)+ +-- *Context++-- | Context options for the different backends.+-- Using an option in a backend that doesn't support it will simply do nothing.+data ContextOption+ = TuningParameters [(String, CSize)] -- ^All backends+ | CacheFile String -- ^All backends+ | Debug Int -- ^All backends+ | Log Int -- ^All backends+ | Profile Int -- ^All backends+ | Device String -- ^GPU backends+ | LoadProgram String -- ^GPU backends+ | DumpProgram String -- ^GPU backends+ | DefaultThreadBlockSize Int -- ^GPU backends+ | DefaultGridSize Int -- ^GPU backends+ | DefaultTileSize Int -- ^GPU backends+ | Platform String -- ^OpenCL+ | BuildOptions [String] -- ^OpenCL+ | NvrtcOptions [String] -- ^Cuda+ | NumThreads Int -- ^Multicore++-- |Each generated library has its own instance of @Context@ +class Context c where+ type RawContext c = raw | raw -> c+ type RawConfig c = cfg | cfg -> c+ -- wrapping+ wrapRawContext :: (ReferenceCounter, ForeignPtr (RawContext c)) -> c+ unwrapRawContext :: c -> (ReferenceCounter, ForeignPtr (RawContext c))+ -- general+ newContext :: Ptr (RawConfig c) -> IO (Ptr (RawContext c))+ freeContext :: Ptr (RawContext c) -> IO ()+ clearCaches :: Ptr (RawContext c) -> IO Int + syncContext :: Ptr (RawContext c) -> IO Int+ -- reporting+ getError :: Ptr (RawContext c) -> IO CString+ getReport :: Ptr (RawContext c) -> IO CString+ -- profiling + pauseProfiling :: Ptr (RawContext c) -> IO ()+ unpauseProfiling :: Ptr (RawContext c) -> IO ()+ -- configuration+ newConfig :: IO (Ptr (RawConfig c))+ freeConfig :: Ptr (RawConfig c) -> IO ()+ -- tuning+ setTuningParam :: Ptr (RawConfig c) -> CString -> CSize -> IO Int+ -- general options+ setCacheFile :: Ptr (RawConfig c) -> CString -> IO ()+ setDebug :: Ptr (RawConfig c) -> Int -> IO () + setLog :: Ptr (RawConfig c) -> Int -> IO ()+ setProfile :: Ptr (RawConfig c) -> Int -> IO ()+ -- Cuda and OpenCL options+ setDevice :: Ptr (RawConfig c) -> CString -> IO ()+ setDefaultThreadBlockSize :: Ptr (RawConfig c) -> Int -> IO ()+ setDefaultGridSize :: Ptr (RawConfig c) -> Int -> IO ()+ setDefaultTileSize :: Ptr (RawConfig c) -> Int -> IO ()+ -- OpenCL options+ setPlatform :: Ptr (RawConfig c) -> CString -> IO ()+ --setLoadBinary :: Ptr (RawConfig c) -> CString -> IO ()+ --setDumpBinary :: Ptr (RawConfig c) -> CString -> IO ()+ setBuildOption :: Ptr (RawConfig c) -> CString -> IO ()+ setNvrtcOption :: Ptr (RawConfig c) -> CString -> IO ()+ setNumThreads :: Ptr (RawConfig c) -> Int -> IO ()+++-- |implementation of options not available for backend - does nothing+voidOption :: config -> parameter -> IO ()+voidOption _ _ = return ()++-- |sets option and returns any error messages and post config finalizer operations+setContextOption :: (Context c) => Ptr (RawConfig c) -> ContextOption -> IO (String, IO ())+setContextOption config option = case option of+ TuningParameters ps -> fmap (\(errs, fins) -> (concat errs, sequence_ fins))+ $ fmap unzip+ $ mapM (\(n, v) -> withCString n (\cn -> setTuningParam config cn v >>= \i -> if i == 0 + then return ("", return ()) + else return ("Tuning parameter \"" ++ n ++ "\" could not be set.\n", return ()))) ps + CacheFile fn -> newCString fn >>= \cn -> setCacheFile config cn >> return ("", free cn)+ Debug i -> nofin $ setDebug config i+ Log i -> nofin $ setLog config i+ Profile i -> nofin $ setProfile config i+ Device s -> nofin $ withCString s (setDevice config)+ DefaultThreadBlockSize s -> nofin $ setDefaultThreadBlockSize config s+ DefaultGridSize s -> nofin $ setDefaultGridSize config s+ DefaultTileSize s -> nofin $ setDefaultTileSize config s+ Platform p -> nofin $ withCString p (setPlatform config)+ BuildOptions os -> nofin $ mapM_ (\o -> withCString o (setBuildOption config)) os+ NvrtcOptions os -> nofin $ mapM_ (\o -> withCString o (setNvrtcOption config)) os+ NumThreads n -> nofin $ setNumThreads config n+ where nofin a = a >> return ("", return ())++-- | Make new context with a list of options+mkContext :: (Context context) => [ContextOption] -> IO (context, [String])+mkContext options = do+ config <- newConfig+ (messages, optionFinalizers) <- unzip <$> mapM (setContextOption config) options+ context <- newContext config+ refCounter <- newRefCounter+ finPointer <- newForeignPtr context (contextFinalizer context config optionFinalizers refCounter)+ return (wrapRawContext (refCounter, finPointer), filter (/="") messages)+ where contextFinalizer context config optionFinalizers refCounter = do+ waitForZero refCounter + freeContext context+ freeConfig config+ sequence_ optionFinalizers++-- *Error handling+emitError :: (Context context) => context -> IO a+emitError context = do+ cs <- inContext context getError+ s <- peekCString cs+ free cs+ error s++clearError :: (Context context) => context -> IO ()+clearError context = inContext context getError >>= free++clearCache :: (Context context) => context -> IO ()+clearCache context+ = inContext context clearCaches >>= \code + -> if code == 0 + then return ()+ else emitError context++-- *Syncing+sync :: (Context context) => context -> IO ()+sync context + = inContext context syncContext >>= \code + -> if code == 0 + then return ()+ else emitError context++-- *Using the Context++-- | Do something in context and get the result.+{-# INLINE inContext #-}+inContext :: (Context c) => c -> (Ptr (RawContext c) -> IO a) -> IO a+inContext c = withForeignPtr (snd $ unwrapRawContext c) ++-- | Do something in context that emits an error code and handle it.+{-# INLINABLE inContextWithError #-}+inContextWithError :: (Context context) => context -> (Ptr (RawContext context) -> IO Int) -> IO ()+inContextWithError context f = do+ code <- attempt+ case code of+ 0 -> success+ 1 -> generalError+ 2 -> programError+ 3 -> outOfMemoryError+ _ -> unknownError+ where+ attempt = inContext context f+ success = return ()+ failure = emitError context+ generalError = failure+ programError = failure+ outOfMemoryError = do+ clearError context+ performGC+ clearCache context+ code' <- attempt+ if code' == 0+ then success+ else failure+ unknownError = failure+
+ src/Futhask/Monad.hs view
@@ -0,0 +1,130 @@+{-# LANGUAGE RankNTypes, ExistentialQuantification, FlexibleInstances, UndecidableInstances, TypeFamilyDependencies, MultiParamTypeClasses, ScopedTypeVariables, FlexibleContexts #-}++module Futhask.Monad where++import System.IO.Unsafe+import Control.Monad.Base+import Control.Monad.Trans+import Control.Monad.Trans.Control+import Control.Monad.Identity++import Futhask.Context++-- *The Monad Transformer++-- | The transformer that passes around the Futhark context.+-- The @context@ parameter is library specific and prevents mixing of different generated libraries.+-- The @c@ parameter is skolem and prevents Futhark values from escaping the monad.+newtype FutT context c m a = FutT (context -> m a)++instance MonadTrans (FutT context c) where+ lift a = FutT (\_ -> a)+ {-# INLINEABLE lift #-}++instance Functor m => Functor (FutT context c m) where+ fmap f (FutT a) = FutT (fmap f.a)+ {-# INLINEABLE fmap #-}++instance Applicative m => Applicative (FutT context c m) where+ pure a = FutT (\_ -> pure a)+ (<*>) (FutT a) (FutT b) = FutT (\c -> a c <*> b c)+ {-# INLINEABLE pure #-}+ {-# INLINEABLE (<*>) #-}++instance Monad m => Monad (FutT context c m) where+ (>>=) (FutT a) f = FutT (\c -> a c >>= (\(FutT b) -> b c) . f)+ {-# INLINEABLE (>>=) #-}++instance (MonadBase b m) => MonadBase b (FutT context c m) where+ liftBase = liftBaseDefault+ {-# INLINEABLE liftBase #-}++instance MonadTransControl (FutT context c) where+ type StT (FutT context c) a = a+ liftWith a = FutT (\c -> a (\(FutT a') -> a' c))+ restoreT = lift+ {-# INLINEABLE liftWith #-}+ {-# INLINEABLE restoreT #-}++instance MonadBaseControl b m => MonadBaseControl b (FutT context c m) where+ type StM (FutT context c m) a = ComposeSt (FutT context c) m a+ liftBaseWith = defaultLiftBaseWith+ restoreM = defaultRestoreM+ {-# INLINEABLE liftBaseWith #-}+ {-# INLINEABLE restoreM #-}++-- **Predefined monads++-- | lazy without side effects, no manual memory management possible+type Fut context c = FutT context c Identity++-- | strict with side effects, manual memory management possible+type FutIO context c = FutT context c IO+++-- *Running the Transformer++-- | Runs the transformer in a given context+runFutTIn :: (Context context) => context -> (forall c. FutT context c m a) -> m a+runFutTIn context (FutT a) = a context++-- | Runs the transformer in a context with a list of options+{-# NOINLINE runFutTWith #-}+runFutTWith :: (Context context) => [ContextOption] -> (forall c. FutT context c m a) -> m a+runFutTWith options a+ = unsafePerformIO+ $ mkContext options >>= \(c, _) -> return $ runFutTIn c a++-- | Runs the transformer with no context options+runFutT :: (Context context) => (forall c. FutT context c m a) -> m a+runFutT = runFutTWith []++-- | Runs the @Fut@ monad in a given context+runFutIn :: (Context context) => context -> (forall c. Fut context c a) -> a+runFutIn context a = runIdentity $ runFutTIn context $ a+++-- | Runs the @Fut@ monad with in a context with a list of options+runFutWith :: (Context context) => [ContextOption] -> (forall c. Fut context c a) -> a+runFutWith options a = runIdentity $ runFutTWith options a++-- | Runs the @Fut@ monad with no context options+runFut :: (Context context) => (forall c. Fut context c a) -> a+runFut = runFutWith []++-- *Misc++-- | Lifts a futhark operation from the identity monad to any other monad+pureFut :: (Context context, Monad m) => Fut context c a -> FutT context c m a+pureFut (FutT a) = FutT (pure . runIdentity . a)++-- | Maps a function to the monad transformer+mapFutT :: (m a -> n b) -> FutT context c m a -> FutT context c n b+mapFutT f (FutT a) = FutT (f.a)++-- | Same as @mapFutT@ but for two arguments+map2FutT :: (m a -> n b -> k c) -> FutT context c' m a -> FutT context c' n b -> FutT context c' k c+map2FutT f (FutT a) (FutT b) = FutT (\c -> f (a c) (b c))++-- *Profiling++-- | Turns on profiling for the argument.+profile :: (Context context, MonadIO m) => FutT context c m a -> FutT context c m a+profile a = do+ FutT (\c -> liftIO $ inContext c unpauseProfiling)+ res <- a+ FutT (\c -> liftIO $ inContext c pauseProfiling)+ return res++-- *Unsafe Lifting++-- | Declares a @FutIO@ value as pure. The value must not consume any arguments or have side effects.+{-# INLINE unsafeFromFutIO #-}+unsafeFromFutIO :: (Context context, Monad m) => FutIO context c a -> FutT context c m a+unsafeFromFutIO (FutT a) = FutT (\ctx -> pure $! unsafePerformIO (a ctx))++-- | Wraps a @(context -> IO a)@ into the generic @FutT c m a@ . Useful for creating new abstractions from the @Raw@ interface functions. Operations should have no external side effects, or the function should be restricted to @MonadIO@.+{-# INLINE unsafeLiftFromIO #-}+unsafeLiftFromIO :: (Context context, Monad m) => (context -> IO a) -> FutT context c m a+unsafeLiftFromIO a = FutT (\ctx -> pure $! unsafePerformIO (a ctx))+
+ src/Futhask/Object.hs view
@@ -0,0 +1,199 @@+{-# LANGUAGE RankNTypes, ExistentialQuantification, FlexibleInstances, UndecidableInstances, TypeFamilyDependencies, MultiParamTypeClasses, ScopedTypeVariables, FlexibleContexts, FunctionalDependencies, ConstraintKinds, QuantifiedConstraints, TypeOperators #-}+{-|+Defines various classes for futhark objects and some utility functions to manage them.+-}++module Futhask.Object where+import Data.Kind+import Data.Word+import Data.Int+import Data.ByteString as B+import Foreign.C+import Foreign.C.String+import Foreign.Ptr+import Foreign.Storable as S+import Foreign.ForeignPtr+import Foreign.Marshal.Array as A+import Foreign.Marshal.Alloc+import Control.Monad.Base+import Control.Monad.Trans+import Control.Concurrent+import Control.Concurrent.MVar+import System.Mem++import Futhask.Array +import Futhask.Array.Rank +import Futhask.Context+import Futhask.Monad++-- * Wrapping Pointers and Managing Memory+-- | The basic functions for wrapping and memory management+class (Context (ObjectContext fo)) => FutharkObject fo where+ type RawObject fo = raw | raw -> fo -- injectivity broke for some reason+ type ObjectContext fo+ wrapRawObject :: ReferenceCounter -> ForeignPtr (RawObject fo) -> fo c+ objectCounter :: fo c -> ReferenceCounter+ objectPointer :: fo c -> ForeignPtr (RawObject fo)+ freeRawObject :: Ptr (RawContext (ObjectContext fo)) -> Ptr (RawObject fo) -> IO Int++-- **Wrapping+-- | Use the raw pointer and return the result +withRawObject :: (FutharkObject fo) => fo c -> (Ptr (RawObject fo) -> IO a) -> IO a+withRawObject fo = withForeignPtr (objectPointer fo)++-- | Wrap raw pointer with a reference counter and context+wrapFO :: (FutharkObject fo) => ObjectContext fo -> Ptr (RawObject fo) -> IO (fo c) +wrapFO context ptr = do+ refCounter <- newRefCounter+ pointer <- newForeignPtrWithRef contextRefcounter ptr (withForeignPtr contextPtr (\cptr -> freeRawObject cptr ptr)) + return $! wrapRawObject refCounter pointer+ where (contextRefcounter, contextPtr) = unwrapRawContext context+++-- **Manual Memory Management++-- | Increments reference counter, useful for concurrent use.+addReferenceFO :: (MonadIO m, FutharkObject fo) => fo c -> FutT (ObjectContext fo) c m ()+addReferenceFO fo = lift . liftIO $ increment (objectCounter fo)++-- | Decrements reference counter, if the counter is zero the object will be finalized, and can no longer be used.+finalizeFO :: (MonadIO m, FutharkObject fo) => fo c -> FutT (ObjectContext fo) c m ()+finalizeFO fo = lift . liftIO $+ let refCounter = objectCounter fo+ in isZero refCounter >>= \b -> if b + then finalizeForeignPtr (objectPointer fo) + else decrement refCounter+++++-- *Value composition and decomposition+class (FutharkObject fo) => FutharkComposite fo where+ type Unpacked fo :: Type -> Type+ pack :: (Monad m) => Unpacked fo c -> FutT (ObjectContext fo) c m (fo c)+ unpack :: (Monad m) => fo c -> FutT (ObjectContext fo) c m (Unpacked fo c)++-- *Projection++-- | Takes a projection function from the @Raw@ interface and applies it.+extractWith + :: (FutharkObject fo, Storable a) + => (Ptr (RawContext (ObjectContext fo)) -> Ptr a -> Ptr (RawObject fo) -> IO Int)+ -> ObjectContext fo -> fo c -> IO a+extractWith f c o = alloca (\ptr -> withRawObject o (\ro -> inContextWithError c (\rc -> f rc ptr ro)) >> S.peek ptr)++-- | Same as `extractWith` but also wraps the extracted object. Only works on futhark objects.+extractFOWith + :: (FutharkObject fo1, FutharkObject fo2, ObjectContext fo2 ~ ObjectContext fo1) + => (Ptr (RawContext (ObjectContext fo1)) -> Ptr (Ptr (RawObject fo2)) -> Ptr (RawObject fo1) -> IO Int)+ -> ObjectContext fo1 -> fo1 c -> IO (fo2 c) +extractFOWith f c o = extractWith f c o >>= wrapFO c++++-- *Array functions+class (FutharkObject arr) => FutIndexable arr where+ type FutRank arr++-- | Basic array functions for primitive arrays+class (FutharkObject fo, FutIndexable fo, Context ctx, ObjectContext fo ~ ctx, Dim rank, FutRank fo ~ rank, Storable elem, PrimElem fo ~ elem) + => FutharkPrimArray' fo ctx rank elem | fo -> ctx rank elem, ctx rank elem -> fo where+ type PrimElem fo+ shapeFPA :: Ptr (RawContext ctx) -> Ptr (RawObject fo) -> IO (Ptr Int64) + valuesFPA :: Ptr (RawContext ctx) -> Ptr (RawObject fo) -> Ptr elem -> IO Int+ newFPA :: Ptr (RawContext ctx) -> Ptr elem -> DimFun rank (Ptr (RawObject fo))+ indexFPA :: Ptr (RawContext ctx) -> Ptr elem -> Ptr (RawObject fo) -> DimFun rank Int++class (FutharkObject fo, FutharkPrimArray' fo (ObjectContext fo) (FutRank fo) (PrimElem fo)) => FutharkPrimArray fo+instance (FutharkObject fo, FutharkPrimArray' fo (ObjectContext fo) (FutRank fo) (PrimElem fo)) => FutharkPrimArray fo++-- | Basic array functions for opaque arrays+class (FutharkObject fo, FutIndexable fo, Context ctx, ObjectContext fo ~ ctx, Dim rank, FutRank fo ~ rank, FutharkObject elem, ObjectContext elem ~ ctx, OpaqueElem fo ~ elem) + => FutharkOpaqueArray' fo ctx rank elem | fo -> ctx rank elem, ctx rank elem -> fo where+ type OpaqueElem fo :: Type -> Type+ shapeFOA :: Ptr (RawContext ctx) -> Ptr (RawObject fo) -> IO (Ptr Int64) + newFOA :: Ptr (RawContext ctx) -> Ptr (RawObject elem) -> DimFun rank (Ptr (RawObject fo))+ indexFOA :: Ptr (RawContext ctx) -> Ptr (Ptr (RawObject elem)) -> Ptr (RawObject fo) -> DimFun rank Int+ setFOA :: Ptr (RawContext ctx) -> Ptr (RawObject fo) -> ptr (RawObject elem) -> DimFun rank Int++class FutharkOpaqueArray' fo (ObjectContext fo) (FutRank fo) (OpaqueElem fo) => FutharkOpaqueArray fo+instance FutharkOpaqueArray' fo (ObjectContext fo) (FutRank fo) (OpaqueElem fo) => FutharkOpaqueArray fo+++++-- * Transfer between Contexts++-- | Allows transfer of objects between contexts +class (FutharkObject fo1, FutharkObject fo2) => Transferable fo1 fo2 where+ transferUp :: (Monad m) => fo2 c2 -> FutT (ObjectContext fo1) c1 (FutT (ObjectContext fo2) c2 m) (fo1 c1)+ transferDown :: (Monad m) => fo1 c1 -> FutT (ObjectContext fo1) c1 (FutT (ObjectContext fo2) c2 m) (fo2 c2)++instance (FutharkOpaque fo) => Transferable fo fo where+ transferUp fo = unsafeLiftFromIO $ \ctx -> alloca $ \sp -> alloca $ \pp -> withRawObject fo $ \op2 -> do+ S.poke pp nullPtr+ inContextWithError ctx $ \cp -> storeOpaque cp op2 pp sp+ sync ctx+ p <- S.peek pp+ op <- inContext ctx $ \cp -> restoreOpaque cp p+ free p+ if op == nullPtr+ then error "Restoration error in transfer"+ else wrapFO ctx op + transferDown fo = unsafeLiftFromIO $ \ctx -> alloca $ \sp -> alloca $ \pp -> withRawObject fo $ \op2 -> do+ S.poke pp nullPtr+ inContextWithError ctx $ \cp -> storeOpaque cp op2 pp sp+ sync ctx+ p <- S.peek pp+ op <- inContext ctx $ \cp -> restoreOpaque cp p+ free p+ if op == nullPtr+ then error "Restoration error in transfer"+ else wrapFO ctx op ++-- *Reading and Writing to Files++-- | Serialization of opaques+class (FutharkObject fo) => FutharkOpaque fo where+ storeOpaque :: Ptr (RawContext (ObjectContext fo)) -> Ptr (RawObject fo) -> Ptr (Ptr CChar) -> Ptr CSize -> IO Int+ restoreOpaque :: Ptr (RawContext (ObjectContext fo)) -> Ptr CChar -> IO (Ptr (RawObject fo))++-- | encoding and decoding objects+class (Monad m) => Serializable m a where+ encode :: a -> m ByteString+ decode :: ByteString -> m (Maybe a)++-- | write object to file+store fn a = encode a >>= lift . B.writeFile fn++-- | read object from file+load fn = lift (B.readFile fn) >>= decode ++instance (FutharkOpaque fo, FutharkObject fo, ObjectContext fo ~ ctx, Monad m)+ => Serializable (FutT ctx c m) (fo c) where + encode fo = unsafeLiftFromIO $ \ctx -> alloca $ \sp -> alloca $ \pp -> withRawObject fo $ \op -> do+ S.poke pp nullPtr+ inContextWithError ctx $ \cp -> storeOpaque cp op pp sp+ sync ctx+ p <- S.peek pp+ s <- S.peek sp+ bs <- packCStringLen (p, fromIntegral s)+ free p+ pure bs+ decode bs = unsafeLiftFromIO $ \ctx -> useAsCString bs $ \cs -> do+ op <- inContext ctx $ \cp -> restoreOpaque cp cs+ if op == nullPtr+ then pure Nothing+ else fmap Just $ wrapFO ctx op++-- * Conversion ++-- | Convert values to and from Futhark+class FutharkObject fo => Convertible fo where+ type Native fo+ toFuthark :: Monad m => Native fo -> FutT (ObjectContext fo) c m (fo c)+ fromFuthark :: Monad m => fo c -> FutT (ObjectContext fo) c m (Native fo)++++
+ src/Futhask/PrimTypes.hs view
@@ -0,0 +1,23 @@+{-|+Type synonyms to more closely resemble futhark types.+-}++module Futhask.PrimTypes (F16,F32,F64,I8,I16,I32,I64,U8,U16,U32,U64,CBool(..)) where+import qualified Data.Int as I+import qualified Data.Word as U+import qualified GHC.Float as F+import qualified Numeric.Half as F+import Foreign.C.Types (CBool(..))+type F16 = F.Half+type F32 = F.Float+type F64 = F.Double+type I8 = I.Int8 +type I16 = I.Int16 +type I32 = I.Int32+type I64 = I.Int64+type U8 = U.Word8 +type U16 = U.Word16 +type U32 = U.Word32+type U64 = U.Word64+ +