indexed-list-literals (empty) → 0.1.0.0
raw patch · 6 files changed
+260/−0 lines, 6 filesdep +OneTupledep +basedep +indexed-list-literalssetup-changed
Dependencies added: OneTuple, base, indexed-list-literals
Files
- ChangeLog.md +0/−0
- LICENSE +30/−0
- Setup.hs +2/−0
- indexed-list-literals.cabal +76/−0
- src/Data/IndexedListLiterals.hs +107/−0
- test/Docs.hs +45/−0
+ ChangeLog.md view
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2018, David Millar-Durrant++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 David Millar-Durrant 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.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ indexed-list-literals.cabal view
@@ -0,0 +1,76 @@+-- Initial indexed-container-literals.cabal generated by cabal init. For +-- further documentation, see http://haskell.org/cabal/users-guide/++name: indexed-list-literals+version: 0.1.0.0+synopsis: Type safe indexed list literals+homepage: https://github.com/davidm-d/indexed-list-literals+license: BSD3+license-file: LICENSE+author: David Millar-Durrant+maintainer: dmillardurrant@gmail.com+description:+ This is an incredibly simple library, which makes writing lists where the length is known at compile time a little bit nicer.+ .+ If you write a function with the signature+ .+ > vector :: ILL input length output => input -> Vector length output+ then+ .+ > v :: Vector 3 Int+ > v = vector (1,2,3)+ >+ > x :: Vector 0 Double+ > x = vector $ ZeroTuple @Double+ >+ > y :: Vector 1 Double+ > y = vector (OneTuple 1)+ >+ > z :: Vector 2 String+ > z = vector ("Hello", "World")+ .+ If want matrix literals you can write a function+ .+ > matrix :: (ILL row width ty, ILL matrix height row) => matrix -> Matrix width height ty+ then+ .+ > a :: Matrix 0 0 Bool+ > a = matrix $ ZeroTuple @(ZeroTuple Bool)+ >+ > b :: Matrix 1 2 String+ > b = matrix $ OneTuple ("Hello","World")+ >+ > c :: Matrix 4 5 Double+ > c = matrix ((1,2,3,0,0)+ > ,(4,5,6,0,0)+ > ,(7,8,9,0,0)+ > ,(0,0,0,0,0))+ The full code is in test\/Docs.hs+ .+ This only supports literals of length up to 20, though that can be easily extended using the code generator in src\/Data\/IndexedListLiterals.hs++-- copyright: +category: Data+build-type: Simple+extra-source-files: ChangeLog.md+cabal-version: >=1.10++library+ exposed-modules: Data.IndexedListLiterals+ -- other-modules: + -- other-extensions: + build-depends: base >=4.9 && <= 4.11+ , OneTuple >= 0.2.1+ hs-source-dirs: src+ default-language: Haskell2010++test-suite IndexedListLiterals-test+ type: exitcode-stdio-1.0+ main-is: Docs.hs+ build-depends: base, indexed-list-literals+ hs-source-dirs: test+ default-language: Haskell2010++source-repository head+ type: git+ location: https://github.com/davidm-d/indexed-list-literals
+ src/Data/IndexedListLiterals.hs view
@@ -0,0 +1,107 @@+{-# Language+ DataKinds,+ MultiParamTypeClasses,+ TypeInType,+ ConstraintKinds,+ FunctionalDependencies,+ FlexibleInstances+ #-}+module Data.IndexedListLiterals (+ IndexedListLiterals(..)+ , ILL+ , module Data.Tuple.OneTuple+ , ZeroTuple(..)+ ) where++import GHC.TypeNats+import Data.Kind+import Data.Tuple.OneTuple+-- import Control.Monad++-- | An alias for IndexedListLiterals+type ILL = IndexedListLiterals++-- | A type class which allows you to write tuples which can be transformed into a list+-- the length of the list is also provided as a Nat+class IndexedListLiterals (input :: Type) (length :: Nat) (output :: Type) | output length -> input, input -> output length where+ toList :: input -> [output]++instance IndexedListLiterals (ZeroTuple a) 0 a where+ toList ZeroTuple = []++instance IndexedListLiterals (OneTuple a) 1 a where+ toList (OneTuple a) = [a]++-- | Intuitively the zero tuple is () or Void but this breaks the Functional Dependency "input -> output length" stopping reliable inference, so this constructor is used to preserve type information+data ZeroTuple a = ZeroTuple++-- all code generated below comes from this function+-- generate :: Int -- ^ up to N+-- -> String+-- generate n = unlines $ join $ map ("":) $ take n $ dropOneTuple res where+-- values = map ((:) 'a' . show) [1 :: Int ..]+-- types = "a" : types+-- withCommas = scanl1 (\a b -> a++","++b)+-- className = "IndexedListLiterals"+-- template tys vals length =+-- ["instance " ++ className ++ " (" ++ tys ++ ") " ++ show length ++ " " ++ head types ++ " where"+-- ," toList (" ++ vals ++ ") = [" ++ vals ++ "]"]+-- res = zipWith3 template (withCommas types) (withCommas values) [0 :: Int ..]+-- dropOneTuple = tail++instance IndexedListLiterals (a,a) 2 a where+ toList (a1,a2) = [a1,a2]++instance IndexedListLiterals (a,a,a) 3 a where+ toList (a1,a2,a3) = [a1,a2,a3]++instance IndexedListLiterals (a,a,a,a) 4 a where+ toList (a1,a2,a3,a4) = [a1,a2,a3,a4]++instance IndexedListLiterals (a,a,a,a,a) 5 a where+ toList (a1,a2,a3,a4,a5) = [a1,a2,a3,a4,a5]++instance IndexedListLiterals (a,a,a,a,a,a) 6 a where+ toList (a1,a2,a3,a4,a5,a6) = [a1,a2,a3,a4,a5,a6]++instance IndexedListLiterals (a,a,a,a,a,a,a) 7 a where+ toList (a1,a2,a3,a4,a5,a6,a7) = [a1,a2,a3,a4,a5,a6,a7]++instance IndexedListLiterals (a,a,a,a,a,a,a,a) 8 a where+ toList (a1,a2,a3,a4,a5,a6,a7,a8) = [a1,a2,a3,a4,a5,a6,a7,a8]++instance IndexedListLiterals (a,a,a,a,a,a,a,a,a) 9 a where+ toList (a1,a2,a3,a4,a5,a6,a7,a8,a9) = [a1,a2,a3,a4,a5,a6,a7,a8,a9]++instance IndexedListLiterals (a,a,a,a,a,a,a,a,a,a) 10 a where+ toList (a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) = [a1,a2,a3,a4,a5,a6,a7,a8,a9,a10]++instance IndexedListLiterals (a,a,a,a,a,a,a,a,a,a,a) 11 a where+ toList (a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11) = [a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11]++instance IndexedListLiterals (a,a,a,a,a,a,a,a,a,a,a,a) 12 a where+ toList (a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12) = [a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12]++instance IndexedListLiterals (a,a,a,a,a,a,a,a,a,a,a,a,a) 13 a where+ toList (a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13) = [a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13]++instance IndexedListLiterals (a,a,a,a,a,a,a,a,a,a,a,a,a,a) 14 a where+ toList (a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14) = [a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14]++instance IndexedListLiterals (a,a,a,a,a,a,a,a,a,a,a,a,a,a,a) 15 a where+ toList (a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15) = [a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15]++instance IndexedListLiterals (a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a) 16 a where+ toList (a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16) = [a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16]++instance IndexedListLiterals (a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a) 17 a where+ toList (a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17) = [a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17]++instance IndexedListLiterals (a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a) 18 a where+ toList (a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18) = [a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18]++instance IndexedListLiterals (a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a) 19 a where+ toList (a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19) = [a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19]++instance IndexedListLiterals (a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a) 20 a where+ toList (a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20) = [a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20]
+ test/Docs.hs view
@@ -0,0 +1,45 @@+{-# Language TypeApplications, DataKinds, TypeInType, KindSignatures #-}++import Data.IndexedListLiterals+import GHC.TypeLits+import Data.Kind++data Matrix (x :: Nat) (y :: Nat) (ty :: Type)++data Vector (length :: Nat) (ty :: Type)++vector :: ILL input length output => input -> Vector length output+vector = undefined++v :: Vector 3 Int+v = vector (1,2,3)++x :: Vector 0 Double+x = vector $ ZeroTuple @Double++y :: Vector 1 Double+y = vector (OneTuple 1)++z :: Vector 2 String+z = vector ("Hello", "World")++matrix :: (ILL row width ty, ILL matrix height row) => matrix -> Matrix height width ty+matrix = undefined++a :: Matrix 0 0 Bool+a = matrix $ ZeroTuple @(ZeroTuple Bool)++b :: Matrix 1 2 String+b = matrix $ OneTuple ("Hello","World")++c :: Matrix 4 5 Double+c = matrix ((1,2,3,0,0)+ ,(4,5,6,0,0)+ ,(7,8,9,0,0)+ ,(0,0,0,0,0))++-- | just making sure the docs type check+main :: IO ()+main = do+ _ <- return (a,b,c,v,x,y,z)+ return ()