{-# Language
DataKinds
, MultiParamTypeClasses
, TypeInType
, ConstraintKinds
, FunctionalDependencies
, FlexibleInstances
, TypeApplications
, RankNTypes
, ScopedTypeVariables
#-}
module Data.IndexedListLiterals (
IndexedListLiterals(..)
, ILL
, module Data.Tuple.Only
, ZeroTuple(..)
, len
, fromList
, fromListP
) where
import GHC.TypeLits
import Data.Kind
import Data.Tuple.Only
import Data.Proxy
import GHC.Stack
import Control.Monad
type ILL = IndexedListLiterals
fromListP :: forall input (length :: Nat) output len.
(KnownNat length, ILL input length output)
=> len length -> [output] -> Maybe input
fromListP _length = fromList
len :: Proxy a
len = Proxy
fromList :: forall input (length :: Nat) output.
(KnownNat length, ILL input length output)
=> [output] -> Maybe input
fromList xs
| length xs == i = Just $ fromList' xs
| otherwise = Nothing
where i = fromIntegral $ natVal (len @length)
class IndexedListLiterals (input :: Type) (length :: Nat) (output :: Type) | output length -> input, input -> output length where
toList :: input -> [output]
fromList' :: [output] -> input
instance IndexedListLiterals (ZeroTuple a) 0 a where
toList ZeroTuple = []
fromList' [] = ZeroTuple
instance IndexedListLiterals (Only a) 1 a where
toList (Only a) = [a]
fromList' [a] = Only a
data ZeroTuple a = ZeroTuple
generate :: Int
-> 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 ++ "]"
," fromList' [" ++ vals ++ "] = (" ++ vals ++ ")"
]
res = zipWith3 template (withCommas types) (withCommas values) [1 :: Int ..]
dropOneTuple = tail
instance IndexedListLiterals (a,a) 2 a where
toList (a1,a2) = [a1,a2]
fromList' [a1,a2] = (a1,a2)
instance IndexedListLiterals (a,a,a) 3 a where
toList (a1,a2,a3) = [a1,a2,a3]
fromList' [a1,a2,a3] = (a1,a2,a3)
instance IndexedListLiterals (a,a,a,a) 4 a where
toList (a1,a2,a3,a4) = [a1,a2,a3,a4]
fromList' [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]
fromList' [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]
fromList' [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]
fromList' [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]
fromList' [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]
fromList' [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]
fromList' [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]
fromList' [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]
fromList' [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]
fromList' [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]
fromList' [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]
fromList' [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]
fromList' [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]
fromList' [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]
fromList' [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]
fromList' [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]
fromList' [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)