numhask-array 0.8.0 → 0.9.0
raw patch · 6 files changed
+111/−44 lines, 6 filesdep −deepseqdep ~doctestdep ~numhask
Dependencies removed: deepseq
Dependency ranges changed: doctest, numhask
Files
- numhask-array.cabal +15/−9
- src/NumHask/Array/Dynamic.hs +34/−8
- src/NumHask/Array/Fixed.hs +48/−6
- src/NumHask/Array/Shape.hs +10/−6
- stack.yaml +0/−10
- test/test.hs +4/−5
numhask-array.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.4 name: numhask-array-version: 0.8.0+version: 0.9.0 synopsis: Multi-dimensional array interface for numhask. description:@@ -8,7 +8,6 @@ . == Usage .- >>> {-# LANGUAGE NegativeLiterals #-} >>> {-# LANGUAGE RebindableSyntax #-} >>> import NumHask.Prelude >>> import NumHask.Array@@ -36,12 +35,11 @@ license-file: LICENSE tested-with:- GHC==8.10.1+ GHC==8.10.1 GHC==9.0.1 build-type: Simple extra-source-files: readme.md- stack.yaml source-repository head type: git@@ -57,12 +55,13 @@ -Wincomplete-record-updates -Wincomplete-uni-patterns -Wredundant-constraints+ -fwrite-ide-info+ -hiedir=.hie build-depends: base >=4.11 && <5, adjunctions >=4.0 && <5,- deepseq >=1.4.2.0 && <2, distributive >=0.4 && <0.7,- numhask >= 0.7 && <0.8,+ numhask >= 0.8 && <0.9, vector >=0.10 && <0.13, exposed-modules: NumHask.Array@@ -80,7 +79,14 @@ default-extensions: build-depends: base >=4.11 && <5,- doctest >=0.13 && <0.17,- numhask-array,- numhask >=0.7 && <0.8,+ doctest >=0.13 && <0.19,+ numhask-array default-language: Haskell2010+ ghc-options:+ -Wall+ -Wcompat+ -Wincomplete-record-updates+ -Wincomplete-uni-patterns+ -Wredundant-constraints+ -fwrite-ide-info+ -hiedir=.hie
src/NumHask/Array/Dynamic.hs view
@@ -1,17 +1,18 @@ {-# LANGUAGE DataKinds #-}-{-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE RankNTypes #-}+{-# LANGUAGE RebindableSyntax #-} {-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE StrictData #-} {-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE NoStarIsType #-} {-# OPTIONS_GHC -Wno-redundant-constraints #-} {-# OPTIONS_GHC -fno-warn-incomplete-uni-patterns #-}+{-# OPTIONS_GHC -fno-warn-incomplete-patterns #-} -- | Arrays with a dynamic shape. module NumHask.Array.Dynamic@@ -42,6 +43,7 @@ append, reorder, expand,+ apply, contract, dot, mult,@@ -65,11 +67,11 @@ ) where -import Data.List ((!!))+import Data.List (intercalate) import qualified Data.Vector as V import GHC.Show (Show (..)) import NumHask.Array.Shape-import NumHask.Prelude as P hiding (product, transpose)+import NumHask.Prelude as P hiding (product) -- $setup -- >>> :set -XDataKinds@@ -92,7 +94,7 @@ -- [17, 18, 19, 20], -- [21, 22, 23, 24]]] data Array a = Array {shape :: [Int], unArray :: V.Vector a}- deriving (Eq, Ord, NFData, Generic)+ deriving (Eq, Ord, Generic) instance Functor Array where fmap f (Array s a) = Array s (V.map f a)@@ -109,7 +111,7 @@ where go n a'@(Array l' m) = case length l' of- 0 -> maybe (throw (NumHaskException "empty scalar")) GHC.Show.show (head m)+ 0 -> GHC.Show.show (V.head m) 1 -> "[" ++ intercalate ", " (GHC.Show.show <$> V.toList m) ++ "]" x -> "["@@ -182,8 +184,8 @@ -- [[1, 0], -- [0, 1], -- [0, 0]]-ident :: (Num a) => [Int] -> Array a-ident ds = tabulate ds (bool 0 1 . isDiag)+ident :: (Additive a, Multiplicative a) => [Int] -> Array a+ident ds = tabulate ds (bool zero one . isDiag) where isDiag [] = True isDiag [_] = True@@ -406,6 +408,30 @@ expand f a b = tabulate ((++) (shape a) (shape b)) (\i -> f (index a (take r i)) (index b (drop r i))) where r = rank (shape a)++-- | Apply an array of functions to each array of values.+--+-- This is in the spirit of the applicative functor operation (<*>).+--+-- > expand f a b == apply (fmap f a) b+--+-- >>> apply ((*) <$> v) v+-- [[1, 2, 3],+-- [2, 4, 6],+-- [3, 6, 9]]+--+-- >>> let b = fromFlatList [2,3] [1..6] :: Array Int+-- >>> contract sum [1,2] (apply (fmap (*) b) (transpose b))+-- [[14, 32],+-- [32, 77]]+--+apply ::+ Array (a -> b) ->+ Array a ->+ Array b+apply f a = tabulate ((++) (shape f) (shape a)) (\i -> index f (take r i) (index a (drop r i)))+ where+ r = rank (shape f) -- | Contract an array by applying the supplied (folding) function on diagonal elements of the dimensions. --
src/NumHask/Array/Fixed.hs view
@@ -7,14 +7,16 @@ {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE RankNTypes #-}+{-# LANGUAGE RebindableSyntax #-} {-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE StrictData #-} {-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-}-{-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE NoStarIsType #-} {-# OPTIONS_GHC -Wno-redundant-constraints #-} {-# OPTIONS_GHC -fno-warn-unused-imports #-}+{-# OPTIONS_GHC -fno-warn-incomplete-patterns #-} -- | Arrays with a fixed shape. module NumHask.Array.Fixed@@ -43,6 +45,7 @@ append, reorder, expand,+ apply, contract, dot, mult,@@ -76,7 +79,6 @@ ) where -import Control.Category (id) import Data.Distributive (Distributive (..)) import Data.Functor.Rep import Data.List ((!!))@@ -86,7 +88,8 @@ import GHC.TypeLits import qualified NumHask.Array.Dynamic as D import NumHask.Array.Shape-import NumHask.Prelude as P hiding (identity, transpose)+import NumHask.Prelude as P hiding (toList)+import Data.Proxy -- $setup -- >>> :set -XDataKinds@@ -110,8 +113,8 @@ -- [21, 22, 23, 24]]] -- -- >>> [1,2,3] :: Array '[2,2] Int--- [[*** Exception: NumHaskException {errorMessage = "shape mismatch"}-newtype Array s a = Array {unArray :: V.Vector a} deriving (Eq, Ord, NFData, Functor, Foldable, Generic, Traversable)+-- *** Exception: NumHaskException {errorMessage = "shape mismatch"}+newtype Array s a = Array {unArray :: V.Vector a} deriving (Eq, Ord, Functor, Foldable, Generic, Traversable) instance (HasShape s, Show a) => Show (Array s a) where show a = GHC.Show.show (toDynamic a)@@ -241,7 +244,7 @@ -- | convert to a dynamic array with shape at the value level. toDynamic :: (HasShape s) => Array s a -> D.Array a-toDynamic a = D.fromFlatList (shape a) (P.toList a)+toDynamic a = D.fromFlatList (shape a) (toList a) -- | Use a dynamic array in a fixed context. --@@ -631,6 +634,44 @@ where r = rank (shape a) +-- | Apply an array of functions to each array of values.+--+-- This is in the spirit of the applicative functor operation (<*>).+--+-- > expand f a b == apply (fmap f a) b+--+-- >>> apply ((*) <$> v) v+-- [[1, 2, 3],+-- [2, 4, 6],+-- [3, 6, 9]]+--+-- Arrays can't be applicative functors in haskell because the changes in shape are reflected in the types.+--+-- > :t apply+-- apply+-- :: (HasShape s, HasShape s', HasShape (s ++ s')) =>+-- Array s (a -> b) -> Array s' a -> Array (s ++ s') b+-- > :t (<*>)+-- (<*>) :: Applicative f => f (a -> b) -> f a -> f b+--+-- >>> let b = [1..6] :: Array '[2,3] Int+-- >>> contract sum (Proxy :: Proxy '[1,2]) (apply (fmap (*) b) (transpose b))+-- [[14, 32],+-- [32, 77]]+--+apply ::+ forall s s' a b.+ ( HasShape s,+ HasShape s',+ HasShape ((++) s s')+ ) =>+ Array s (a -> b) ->+ Array s' a ->+ Array ((++) s s') b+apply f a = tabulate (\i -> index f (take r i) (index a (drop r i)))+ where+ r = rank (shape f)+ -- | Contract an array by applying the supplied (folding) function on diagonal elements of the dimensions. -- -- This generalises a tensor contraction by allowing the number of contracting diagonals to be other than 2, and allowing a binary operator other than multiplication.@@ -982,3 +1023,4 @@ n = fromIntegral $ natVal @n Proxy k = fromIntegral $ natVal @k Proxy {-# INLINE mmult #-}+
src/NumHask/Array/Shape.hs view
@@ -4,15 +4,18 @@ {-# LANGUAGE GADTs #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE RankNTypes #-}+{-# LANGUAGE RebindableSyntax #-} {-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE StrictData #-} {-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeInType #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE UndecidableInstances #-}-{-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE NoStarIsType #-} {-# OPTIONS_GHC -Wall #-}+{-# OPTIONS_GHC -fno-warn-incomplete-patterns #-}+{-# OPTIONS_GHC -fno-warn-unused-top-binds #-} -- | Functions for manipulating shape. The module tends to supply equivalent functionality at type-level and value-level with functions of the same name (except for capitalization). module NumHask.Array.Shape@@ -74,10 +77,11 @@ ) where -import Data.List ((!!)) import Data.Type.Bool import GHC.TypeLits as L import NumHask.Prelude as P hiding (Last, minimum)+import Data.Proxy+import Data.Type.Equality -- | The Shape type holds a [Nat] at type level and the equivalent [Int] at value level. -- Using [Int] as the index for an array nicely represents the practical interests and constraints downstream of this high-level API: densely-packed numbers (reals or integrals), indexed and layered.@@ -166,7 +170,7 @@ checkIndexes is n = all (`checkIndex` n) is type family CheckIndexes (i :: [Nat]) (n :: Nat) :: Bool where- CheckIndexes '[] n = 'True+ CheckIndexes '[] _ = 'True CheckIndexes (i : is) n = CheckIndex i n && CheckIndexes is n -- | dimension i is the i'th dimension of a Shape@@ -320,7 +324,7 @@ (s !! i) ': TakeIndexes s is type family (a :: [k]) !! (b :: Nat) :: k where- (!!) '[] i = L.TypeError ('Text "Index Underflow")+ (!!) '[] _ = L.TypeError ('Text "Index Underflow") (!!) (x : _) 0 = x (!!) (_ : xs) i = (!!) xs (i - 1) @@ -395,8 +399,8 @@ ~ 'True -- | remove 1's from a list-squeeze' :: (Eq a, Num a) => [a] -> [a]-squeeze' = filter (/= 1)+squeeze' :: (Eq a, Multiplicative a) => [a] -> [a]+squeeze' = filter (/= one) type family Squeeze (a :: [Nat]) where Squeeze '[] = '[]
− stack.yaml
@@ -1,10 +0,0 @@-resolver: nightly-2020-11-19--packages:- - .--extra-deps:- - numhask-0.7.0.0- - protolude-0.3.0- - random-1.2.0- - splitmix-0.1.0.3
test/test.hs view
@@ -1,20 +1,19 @@ {-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE RebindableSyntax #-} {-# LANGUAGE ScopedTypeVariables #-} {-# OPTIONS_GHC -Wall #-} module Main where -import NumHask.Prelude as P+import Prelude as P import Test.DocTest main :: IO () main = do- putStrLn ("NumHask.Array.Fixed DocTest turned on" :: Text)+ putStrLn "NumHask.Array.Fixed DocTest turned on" doctest ["src/NumHask/Array/Fixed.hs"]- putStrLn ("NumHask.Array.Shape DocTest turned on" :: Text)+ putStrLn "NumHask.Array.Shape DocTest turned on" doctest ["src/NumHask/Array/Shape.hs"]- putStrLn ("NumHask.Array.Dynamic DocTest turned on" :: Text)+ putStrLn "NumHask.Array.Dynamic DocTest turned on" doctest ["src/NumHask/Array/Dynamic.hs"]