packages feed

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 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 ()