{-# OPTIONS_GHC -Wall -funbox-strict-fields #-}
{-# LANGUAGE DeriveDataTypeable, ScopedTypeVariables #-}
module Data.ArithEncode.Basic(
Encoding,
mkEncoding,
mkInfEncoding,
IllegalArgument(..),
encode,
decode,
size,
inDomain,
identity,
singleton,
integral,
interval,
fromHashableList,
fromOrdList,
wrap,
optional,
mandatory,
nonzero,
exclude,
either,
union,
pair,
triple,
quad,
quint,
sextet,
septet,
octet,
nonet,
dectet,
power,
set,
hashSet,
seq,
boundedSeq,
recursive,
recursive2,
recursive3,
recursive4,
recursive5,
recursive6,
recursive7,
recursive8,
recursive9,
recursive10
) where
import Control.Exception
import Control.Monad
import Data.Array.IArray(Array)
import Data.Bits
import Data.Hashable
import Data.List hiding (elem, union)
import Data.Maybe
import Data.Set(Set)
import Data.HashSet(HashSet)
import Data.Typeable
import Prelude hiding (elem, either, seq)
import Math.NumberTheory.Powers.Squares
import Math.NumberTheory.Logarithms
import Data.Word
import qualified Data.Array.IArray as Array
import qualified Data.Either as Either
import qualified Data.HashMap.Lazy as HashMap
import qualified Data.HashSet as HashSet
import qualified Data.Map as Map
import qualified Data.Set as Set
data IllegalArgument = IllegalArgument !String
deriving Typeable
instance Show IllegalArgument where
show (IllegalArgument "") = "Illegal argument"
show (IllegalArgument s) = "Illegal argument: " ++ s
instance Exception IllegalArgument
data Encoding ty =
Encoding {
encEncode :: ty -> Integer,
encDecode :: Integer -> ty,
encSize :: !(Maybe Integer),
encInDomain :: ty -> Bool
}
mkEncoding :: (ty -> Integer)
-> (Integer -> ty)
-> Maybe Integer
-> (ty -> Bool)
-> Encoding ty
mkEncoding encodefunc decodefunc sizeval indomain =
Encoding { encEncode = encodefunc, encDecode = decodefunc,
encSize = sizeval, encInDomain = indomain }
mkInfEncoding :: (ty -> Integer)
-> (Integer -> ty)
-> (ty -> Bool)
-> Encoding ty
mkInfEncoding encodefunc decodefunc indomain =
mkEncoding encodefunc decodefunc Nothing indomain
encode :: Encoding ty
-> ty
-> Integer
encode encoding = encEncode encoding
decode :: Encoding ty
-> Integer
-> ty
decode encoding num
| num < 0 =
throw (IllegalArgument ("decode argument " ++ show num ++ " is negative"))
| maybe False (<= num) (size encoding) =
throw (IllegalArgument ("decode argument " ++ show num ++
" is out of bounds"))
| otherwise = (encDecode encoding) num
size :: Encoding ty
-> Maybe Integer
size = encSize
inDomain :: Encoding ty
-> ty
-> Bool
inDomain encoding = encInDomain encoding
identity :: Encoding Integer
identity = mkInfEncoding id id (>= 0)
singleton :: Eq ty => ty -> Encoding ty
singleton val = mkEncoding (const 0) (const val) (Just 1) (val ==)
integral :: Integral n => Encoding n
integral =
let
encodefunc num
| num < 0 = ((abs (toInteger num) - 1) `shiftL` 1) `setBit` 0
| otherwise = (toInteger num) `shiftL` 1
decodefunc num
| num `testBit` 0 = fromInteger (-((num `shiftR` 1) + 1))
| otherwise = fromInteger (num `shiftR` 1)
in
mkInfEncoding encodefunc decodefunc (const True)
interval :: Integral n
=> n
-> n
-> Encoding n
interval lower upper
| lower <= upper =
let
biglower = toInteger lower
encodefunc num = (toInteger num) - biglower
decodefunc num = fromInteger (num + biglower)
sizeval = Just ((toInteger upper) - (toInteger lower) + 1)
indomainfunc val = lower <= val && val <= upper
in
mkEncoding encodefunc decodefunc sizeval indomainfunc
| otherwise = error "Lower bound is not less than upper bound"
fromHashableList :: forall ty. (Hashable ty, Ord ty)
=> [ty]
-> Encoding ty
fromHashableList elems =
let
len = fromIntegral (length elems)
revmap :: Array Data.Word.Word ty
revmap = Array.listArray (0, len) elems
fwdmap = HashMap.fromList (zip elems [0..len])
encodefunc = toInteger . (HashMap.!) fwdmap
decodefunc = (Array.!) revmap . fromInteger
sizeval = Just (toInteger len)
indomainfunc = (flip HashMap.member) fwdmap
in
mkEncoding encodefunc decodefunc sizeval indomainfunc
fromOrdList :: forall ty . Ord ty
=> [ty]
-> Encoding ty
fromOrdList elems =
let
len = fromIntegral (length elems)
revmap :: Array Word ty
revmap = Array.listArray (0, len) elems
fwdmap = Map.fromList (zip elems [0..len])
encodefunc = toInteger . (Map.!) fwdmap
decodefunc = (Array.!) revmap . fromInteger
sizeval = Just (toInteger len)
indomainfunc = (flip Map.member) fwdmap
in
mkEncoding encodefunc decodefunc sizeval indomainfunc
wrap :: (a -> Maybe b)
-> (b -> Maybe a)
-> Encoding b
-> Encoding a
wrap fwd rev enc @ Encoding { encEncode = encodefunc, encDecode = decodefunc,
encInDomain = indomainfunc } =
let
safefwd val =
case fwd val of
Just val' -> val'
Nothing -> throw (IllegalArgument "No mapping into underlying domain")
saferev val =
case rev val of
Just val' -> val'
Nothing -> throw (IllegalArgument "No mapping into external domain")
in
enc { encEncode = encodefunc . safefwd,
encDecode = saferev . decodefunc,
encInDomain = maybe False indomainfunc . fwd }
optional :: Encoding ty -> Encoding (Maybe ty)
optional Encoding { encEncode = encodefunc, encDecode = decodefunc,
encSize = sizeval, encInDomain = indomainfunc } =
let
newsize = sizeval >>= return . (+ 1)
newindomain = maybe True indomainfunc
newencode Nothing = 0
newencode (Just val) = 1 + encodefunc val
newdecode 0 = Nothing
newdecode num = Just (decodefunc (num - 1))
in
Encoding { encEncode = newencode, encDecode = newdecode,
encSize = newsize, encInDomain = newindomain }
mandatory :: Encoding (Maybe ty) -> Encoding ty
mandatory Encoding { encEncode = encodefunc, encDecode = decodefunc,
encSize = sizeval, encInDomain = indomainfunc } =
let
dec n = n - 1
newencode = dec . encodefunc . Just
newdecode = fromJust . decodefunc . (+ 1)
newsize = sizeval >>= return . dec
newindomain = indomainfunc . Just
in
Encoding { encEncode = newencode, encDecode = newdecode,
encSize = newsize, encInDomain = newindomain }
nonzero :: Encoding ty -> Encoding ty
nonzero enc @ Encoding { encEncode = encodefunc, encDecode = decodefunc,
encSize = sizeval, encInDomain = indomainfunc } =
let
dec n = n - 1
newencode = dec . encodefunc
newdecode = decodefunc . (+ 1)
newsize = sizeval >>= return . dec
newindomain val = indomainfunc val && 0 /= encodefunc val
in
enc { encEncode = newencode, encDecode = newdecode,
encSize = newsize, encInDomain = newindomain }
data BinTree key val =
Branch key val (BinTree key val) (BinTree key val)
| Nil
deriving Show
closestBelow :: Ord key => key -> BinTree key val -> Maybe (key, val)
closestBelow target =
let
closestBelow' out Nil = out
closestBelow' out (Branch k v left right) =
case compare k target of
LT -> closestBelow' (Just (k, v)) right
_ -> closestBelow' out left
in
closestBelow' Nothing
closestWithin :: Ord key => key -> BinTree key val -> Maybe (key, val)
closestWithin target =
let
closestWithin' out Nil = out
closestWithin' out (Branch k v left right) =
case compare k target of
GT -> closestWithin' out left
_ -> closestWithin' (Just (k, v)) right
in
closestWithin' Nothing
toBinTree :: [(key, val)] -> BinTree key val
toBinTree vals =
let
toBinTree' 0 [] = Nil
toBinTree' 0 _ = error "Zero size with non-empty list"
toBinTree' _ [] = error "Empty list with non-zero size"
toBinTree' len vals' =
let
halflo = len `shiftR` 1
halfhi = len - halflo
(lows, (k, v) : highs) = splitAt halflo vals'
left = toBinTree' halflo lows
right = toBinTree' (halfhi - 1) highs
in
Branch k v left right
in
toBinTree' (length vals) vals
exclude :: [ty]
-> Encoding ty
-> Encoding ty
exclude [] enc = enc
exclude excludes enc @ Encoding { encEncode = encodefunc, encDecode = decodefunc,
encSize = sizeval, encInDomain = indomainfunc } =
let
forbidden = HashSet.fromList (map encodefunc excludes)
sortedlist = sort (map encodefunc excludes)
fwdoffsets :: [(Integer, Integer)]
(_, fwdoffsets) = mapAccumL (\offset v -> (offset + 1, (v, offset)))
1 sortedlist
fwdtree = toBinTree fwdoffsets
revoffsets :: [(Integer, Integer)]
revoffsets =
let
foldfun :: [(Integer, Integer)] -> (Integer, Integer) ->
[(Integer, Integer)]
foldfun accum @ ((v', _) : rest) elem @ (v, _)
| v == v' = elem : rest
| otherwise = elem : accum
foldfun _ _ = error "Should not fold over an empty list"
(first : adjusted) =
map (\(v, offset) -> (v - (offset - 1), offset)) fwdoffsets
in
reverse (foldl foldfun [first] adjusted)
revtree = toBinTree revoffsets
toExcluded n =
case closestBelow n fwdtree of
Just (_, offset) -> n - offset
Nothing -> n
fromExcluded n =
case closestWithin n revtree of
Just (_, offset) -> n + offset
Nothing -> n
newEncode = toExcluded . encodefunc
newDecode = decodefunc . fromExcluded
newSize =
do
n <- sizeval
return $! (n - (toInteger (length excludes)))
newInDomain val =
indomainfunc val && not (HashSet.member (encodefunc val) forbidden)
in
enc { encEncode = newEncode, encDecode = newDecode,
encSize = newSize, encInDomain = newInDomain }
either :: Encoding ty1
-> Encoding ty2
-> Encoding (Either ty1 ty2)
either Encoding { encEncode = encode1, encDecode = decode1,
encInDomain = indomain1, encSize = sizeval1 }
Encoding { encEncode = encode2, encDecode = decode2,
encInDomain = indomain2, encSize = sizeval2 } =
let
(isLeft, leftIdxFwd, rightIdxFwd, leftIdxRev, rightIdxRev) =
case (sizeval1, sizeval2) of
(Nothing, Nothing) ->
(\num -> not (testBit num 0),
\idx -> idx `shiftL` 1,
\idx -> setBit (idx `shiftL` 1) 0,
\idx -> idx `shiftR` 1,
\idx -> idx `shiftR` 1)
(Just size1, _) | maybe True (size1 <) sizeval2 ->
let
size1shifted = (size1 `shiftL` 1)
isLeft' num = num < size1shifted && not (testBit num 0)
leftIdxFwd' idx = idx `shiftL` 1
rightIdxFwd' idx
| size1 <= idx = size1shifted + (idx - size1)
| otherwise = setBit (idx `shiftL` 1) 0
leftIdxRev' idx = idx `shiftR` 1
rightIdxRev' idx
| size1shifted <= idx = size1 + (idx - size1shifted)
| otherwise = idx `shiftR` 1
in
(isLeft', leftIdxFwd', rightIdxFwd', leftIdxRev', rightIdxRev')
(_, Just size2) ->
let
size2shifted = (size2 `shiftL` 1)
isLeft' num = num > size2shifted || not (testBit num 0)
leftIdxFwd' idx
| size2 <= idx = size2shifted + (idx - size2)
| otherwise = idx `shiftL` 1
rightIdxFwd' idx = setBit (idx `shiftL` 1) 0
leftIdxRev' idx
| size2shifted <= idx = size2 + (idx - size2shifted)
| otherwise = idx `shiftR` 1
rightIdxRev' idx = idx `shiftR` 1
in
(isLeft', leftIdxFwd', rightIdxFwd', leftIdxRev', rightIdxRev')
_ -> error "This case should never happen"
newSize =
do
size1 <- sizeval1
size2 <- sizeval2
return (size1 + size2)
eitherIndex lfunc rfunc idx
| isLeft idx = lfunc (leftIdxRev idx)
| otherwise = rfunc (rightIdxRev idx)
newEncode = Either.either (leftIdxFwd . encode1) (rightIdxFwd . encode2)
newDecode = eitherIndex (Left . decode1) (Right . decode2)
newInDomain = Either.either indomain1 indomain2
in
Encoding { encEncode = newEncode, encDecode = newDecode,
encSize = newSize, encInDomain = newInDomain }
sortfunc :: Maybe Integer -> Maybe Integer -> Ordering
sortfunc Nothing Nothing = EQ
sortfunc Nothing _ = GT
sortfunc _ Nothing = LT
sortfunc (Just a) (Just b) = compare a b
union :: forall ty.
[Encoding ty]
-> Encoding ty
union [] = error "union encoding with no arguments"
union encodings =
let
numelems :: Int
numelems = length encodings
sortpair (a, _) (b, _) = sortfunc a b
(sizes, sortedencodings) =
unzip (sortBy sortpair (map (\enc -> (size enc, enc)) encodings))
encodingarr :: Array.Array Int (Encoding ty)
encodingarr = Array.listArray (0, numelems - 1) sortedencodings
(fwdmapnum, revmapnum) =
let
sizeclasses =
let
foldfun (ind, accum) elemsize =
case accum of
(elemsize', _) : _ | elemsize == elemsize' ->
(ind + 1, accum)
_ -> (ind + 1, (elemsize, ind) : accum)
(_, out) = foldl foldfun (0, []) sizes
in
reverse out
fwdmapbasic base width num enc =
let
adjustedenc = enc - (numelems - width)
in
((num * toInteger width) + (toInteger adjustedenc) + base)
revmapbasic base width num
| (fromInteger num) < width =
let
adjustedenc = fromInteger num + (numelems - width)
in
(base, adjustedenc)
| otherwise = ((num `quot` toInteger width) + base,
fromInteger (num `mod` toInteger width) +
(numelems - width))
in case sizeclasses of
[ _ ] -> (fwdmapbasic 0 numelems, revmapbasic 0 numelems)
(Just firstsize, _) : rest ->
let
(fwdtree, revtree) =
let
foldfun (lastsize, offset, fwds, revs) (Nothing, idx) =
let
thisnumencs = numelems - idx
in
(undefined, undefined,
(lastsize, (offset, thisnumencs)) : fwds,
(offset, (lastsize, thisnumencs)) : revs)
foldfun (lastsize, offset, fwds, revs) (Just thissize, idx) =
let
thisnumencs = numelems - idx
sizediff = thissize - lastsize
in
(thissize, offset + (sizediff * toInteger thisnumencs),
(lastsize, (offset, thisnumencs)) : fwds,
(offset, (lastsize, thisnumencs)) : revs)
(_, _, fwdvals, revvals) =
foldl foldfun
(firstsize, (firstsize * toInteger numelems), [], [])
rest
in
(toBinTree (reverse fwdvals), toBinTree (reverse revvals))
fwdmap num enc =
case closestWithin num fwdtree of
Nothing -> fwdmapbasic 0 numelems num enc
Just (sizeclass, (base, numencs)) ->
fwdmapbasic base numencs (num - sizeclass) enc
revmap num =
case closestWithin num revtree of
Nothing -> revmapbasic 0 numelems num
Just (offset, (base, numencs)) ->
revmapbasic base numencs (num - offset)
in
(fwdmap, revmap)
_ -> error "Internal error"
encodefunc val =
case findIndex ((flip inDomain) val) sortedencodings of
Just encidx ->
let
enc = (Array.!) encodingarr encidx
num = encode enc val
in
fwdmapnum num encidx
Nothing -> throw (IllegalArgument "Value not in domain of any component")
decodefunc num =
let
(encnum, encidx) = revmapnum num
encoding = (Array.!) encodingarr encidx
in
decode encoding encnum
sizeval =
let
foldfun accum n =
do
accumval <- accum
nval <- n
return (nval + accumval)
in
foldl foldfun (Just 0) sizes
indomainfunc val = any ((flip inDomain) val) sortedencodings
in
Encoding { encEncode = encodefunc, encDecode = decodefunc,
encSize = sizeval, encInDomain = indomainfunc }
isqrt :: Integer -> Integer
isqrt = integerSquareRoot'
mkPairCore :: Encoding ty1 -> Encoding ty2 ->
((ty1, ty2) -> Integer, Integer -> (ty1, ty2), Maybe Integer)
mkPairCore Encoding { encEncode = encode1, encDecode = decode1,
encSize = sizeval1 }
Encoding { encEncode = encode2, encDecode = decode2,
encSize = sizeval2 } =
let
(convertidx, decodefunc) = case (sizeval1, sizeval2) of
(Just maxval, _) ->
let
convertidx' idx1 idx2 = (idx2 * maxval) + idx1
newdecode num = (decode1 (num `mod` maxval), decode2 (num `quot` maxval))
in
(convertidx', newdecode)
(_, Just maxval) ->
let
convertidx' idx1 idx2 = (idx1 * maxval) + idx2
newdecode num = (decode1 (num `quot` maxval), decode2 (num `mod` maxval))
in
(convertidx', newdecode)
(Nothing, Nothing) ->
let
convertidx' idx1 idx2 =
let
sumval = idx1 + idx2
base = (((sumval + 1) * sumval)) `quot` 2
in
base + idx2
newdecode num =
let
sumval = (isqrt ((8 * num) + 1) - 1) `quot` 2
base = (((sumval + 1) * sumval)) `quot` 2
num2 = num - base
num1 = sumval - num2
in
(decode1 num1, decode2 num2)
in
(convertidx', newdecode)
encodefunc (val1, val2) = convertidx (encode1 val1) (encode2 val2)
sizeval =
do
size1 <- sizeval1
size2 <- sizeval2
return (size1 * size2)
in
(encodefunc, decodefunc, sizeval)
pair :: Encoding ty1 -> Encoding ty2 -> Encoding (ty1, ty2)
pair enc1 @ Encoding { encInDomain = indomain1 }
enc2 @ Encoding { encInDomain = indomain2 } =
let
(encodefunc, decodefunc, sizeval) = mkPairCore enc1 enc2
indomainfunc (val1, val2) = indomain1 val1 && indomain2 val2
in
Encoding { encEncode = encodefunc, encDecode = decodefunc,
encSize = sizeval, encInDomain = indomainfunc }
triple :: Encoding ty1 -> Encoding ty2 -> Encoding ty3 ->
Encoding (ty1, ty2, ty3)
triple enc1 enc2 enc3 =
let
fwdshuffle (val1, val2, val3) = ((val1, val2), val3)
revshuffle ((val1, val2), val3) = (val1, val2, val3)
Encoding { encEncode = encodefunc, encDecode = decodefunc,
encSize = sizeval, encInDomain = indomainfunc } =
pair (pair enc1 enc2) enc3
newencode = encodefunc . fwdshuffle
newdecode = revshuffle . decodefunc
newindomain = indomainfunc . fwdshuffle
in
Encoding { encEncode = newencode, encDecode = newdecode,
encSize = sizeval, encInDomain = newindomain }
quad :: Encoding ty1 -> Encoding ty2 -> Encoding ty3 -> Encoding ty4 ->
Encoding (ty1, ty2, ty3, ty4)
quad enc1 enc2 enc3 enc4 =
let
fwdshuffle (val1, val2, val3, val4) = ((val1, val2), (val3, val4))
revshuffle ((val1, val2), (val3, val4)) = (val1, val2, val3, val4)
Encoding { encEncode = encodefunc, encDecode = decodefunc,
encSize = sizeval, encInDomain = indomainfunc } =
pair (pair enc1 enc2) (pair enc3 enc4)
newencode = encodefunc . fwdshuffle
newdecode = revshuffle . decodefunc
newindomain = indomainfunc . fwdshuffle
in
Encoding { encEncode = newencode, encDecode = newdecode,
encSize = sizeval, encInDomain = newindomain }
quint :: Encoding ty1 -> Encoding ty2 -> Encoding ty3 ->
Encoding ty4 -> Encoding ty5 ->
Encoding (ty1, ty2, ty3, ty4, ty5)
quint enc1 enc2 enc3 enc4 enc5 =
let
fwdshuffle (val1, val2, val3, val4, val5) = (((val1, val2), val3), (val4, val5))
revshuffle (((val1, val2), val3), (val4, val5)) = (val1, val2, val3, val4, val5)
Encoding { encEncode = encodefunc, encDecode = decodefunc,
encSize = sizeval, encInDomain = indomainfunc } =
pair (pair (pair enc1 enc2) enc3) (pair enc4 enc5)
newencode = encodefunc . fwdshuffle
newdecode = revshuffle . decodefunc
newindomain = indomainfunc . fwdshuffle
in
Encoding { encEncode = newencode, encDecode = newdecode,
encSize = sizeval, encInDomain = newindomain }
sextet :: Encoding ty1 -> Encoding ty2 -> Encoding ty3 ->
Encoding ty4 -> Encoding ty5 -> Encoding ty6 ->
Encoding (ty1, ty2, ty3, ty4, ty5, ty6)
sextet enc1 enc2 enc3 enc4 enc5 enc6 =
let
fwdshuffle (val1, val2, val3, val4, val5, val6) =
(((val1, val2), val3), ((val4, val5), val6))
revshuffle (((val1, val2), val3), ((val4, val5), val6)) =
(val1, val2, val3, val4, val5, val6)
Encoding { encEncode = encodefunc, encDecode = decodefunc,
encSize = sizeval, encInDomain = indomainfunc } =
pair (pair (pair enc1 enc2) enc3) (pair (pair enc4 enc5) enc6)
newencode = encodefunc . fwdshuffle
newdecode = revshuffle . decodefunc
newindomain = indomainfunc . fwdshuffle
in
Encoding { encEncode = newencode, encDecode = newdecode,
encSize = sizeval, encInDomain = newindomain }
septet :: Encoding ty1 -> Encoding ty2 -> Encoding ty3 -> Encoding ty4 ->
Encoding ty5 -> Encoding ty6 -> Encoding ty7 ->
Encoding (ty1, ty2, ty3, ty4, ty5, ty6, ty7)
septet enc1 enc2 enc3 enc4 enc5 enc6 enc7 =
let
fwdshuffle (val1, val2, val3, val4, val5, val6, val7) =
(((val1, val2), (val3, val4)), ((val5, val6), val7))
revshuffle (((val1, val2), (val3, val4)), ((val5, val6), val7)) =
(val1, val2, val3, val4, val5, val6, val7)
Encoding { encEncode = encodefunc, encDecode = decodefunc,
encSize = sizeval, encInDomain = indomainfunc } =
pair (pair (pair enc1 enc2) (pair enc3 enc4)) (pair (pair enc5 enc6) enc7)
newencode = encodefunc . fwdshuffle
newdecode = revshuffle . decodefunc
newindomain = indomainfunc . fwdshuffle
in
Encoding { encEncode = newencode, encDecode = newdecode,
encSize = sizeval, encInDomain = newindomain }
octet :: Encoding ty1 -> Encoding ty2 -> Encoding ty3 ->
Encoding ty4 -> Encoding ty5 -> Encoding ty6 ->
Encoding ty7 -> Encoding ty8 ->
Encoding (ty1, ty2, ty3, ty4, ty5, ty6, ty7, ty8)
octet enc1 enc2 enc3 enc4 enc5 enc6 enc7 enc8 =
let
fwdshuffle (val1, val2, val3, val4, val5, val6, val7, val8) =
(((val1, val2), (val3, val4)), ((val5, val6), (val7, val8)))
revshuffle (((val1, val2), (val3, val4)), ((val5, val6), (val7, val8))) =
(val1, val2, val3, val4, val5, val6, val7, val8)
Encoding { encEncode = encodefunc, encDecode = decodefunc,
encSize = sizeval, encInDomain = indomainfunc } =
pair (pair (pair enc1 enc2) (pair enc3 enc4))
(pair (pair enc5 enc6) (pair enc7 enc8))
newencode = encodefunc . fwdshuffle
newdecode = revshuffle . decodefunc
newindomain = indomainfunc . fwdshuffle
in
Encoding { encEncode = newencode, encDecode = newdecode,
encSize = sizeval, encInDomain = newindomain }
nonet :: Encoding ty1 -> Encoding ty2 -> Encoding ty3 -> Encoding ty4 ->
Encoding ty5 -> Encoding ty6 -> Encoding ty7 ->
Encoding ty8 -> Encoding ty9 ->
Encoding (ty1, ty2, ty3, ty4, ty5, ty6, ty7, ty8, ty9)
nonet enc1 enc2 enc3 enc4 enc5 enc6 enc7 enc8 enc9 =
let
fwdshuffle (val1, val2, val3, val4, val5, val6, val7, val8, val9) =
((((val1, val2), val3), (val4, val5)), ((val6, val7), (val8, val9)))
revshuffle ((((val1, val2), val3), (val4, val5)), ((val6, val7), (val8, val9))) =
(val1, val2, val3, val4, val5, val6, val7, val8, val9)
Encoding { encEncode = encodefunc, encDecode = decodefunc,
encSize = sizeval, encInDomain = indomainfunc } =
pair (pair (pair (pair enc1 enc2) enc3) (pair enc4 enc5))
(pair (pair enc6 enc7) (pair enc8 enc9))
newencode = encodefunc . fwdshuffle
newdecode = revshuffle . decodefunc
newindomain = indomainfunc . fwdshuffle
in
Encoding { encEncode = newencode, encDecode = newdecode,
encSize = sizeval, encInDomain = newindomain }
dectet :: Encoding ty1 -> Encoding ty2 -> Encoding ty3 -> Encoding ty4 ->
Encoding ty5 -> Encoding ty6 -> Encoding ty7 ->
Encoding ty8 -> Encoding ty9 -> Encoding ty10 ->
Encoding (ty1, ty2, ty3, ty4, ty5, ty6, ty7, ty8, ty9, ty10)
dectet enc1 enc2 enc3 enc4 enc5 enc6 enc7 enc8 enc9 enc10 =
let
fwdshuffle (val1, val2, val3, val4, val5, val6, val7, val8, val9, val10) =
((((val1, val2), val3), (val4, val5)), (((val6, val7), val8), (val9, val10)))
revshuffle ((((val1, val2), val3), (val4, val5)),
(((val6, val7), val8), (val9, val10))) =
(val1, val2, val3, val4, val5, val6, val7, val8, val9, val10)
Encoding { encEncode = encodefunc, encDecode = decodefunc,
encSize = sizeval, encInDomain = indomainfunc } =
pair (pair (pair (pair enc1 enc2) enc3) (pair enc4 enc5))
(pair (pair (pair enc6 enc7) enc8) (pair enc9 enc10))
newencode = encodefunc . fwdshuffle
newdecode = revshuffle . decodefunc
newindomain = indomainfunc . fwdshuffle
in
Encoding { encEncode = newencode, encDecode = newdecode,
encSize = sizeval, encInDomain = newindomain }
toProdList :: Integer -> Integer -> [Integer]
toProdList =
let
productList' accum 1 entropy = reverse (entropy : accum)
productList' _ 0 _ = []
productList' accum count entropy =
let
sumval = (isqrt ((8 * entropy) + 1) - 1) `quot` 2
base = (((sumval + 1) * sumval)) `quot` 2
num2 = entropy - base
num1 = sumval - num2
in
productList' (num1 : accum) (count - 1) num2
in
productList' []
fromProdList :: [Integer] -> Integer
fromProdList [] = 0
fromProdList vals =
let
(first : rest) = reverse vals
fromProdList' accum [] = accum
fromProdList' accum (first' : rest') =
let
sumval = accum + first'
base = (((sumval + 1) * sumval)) `quot` 2
in
fromProdList' (base + accum) rest'
in
fromProdList' first rest
power :: Integer
-> Encoding ty
-> Encoding [ty]
power len Encoding { encEncode = encodefunc, encDecode = decodefunc,
encSize = sizeval, encInDomain = indomainfunc } =
let
(newencode, newdecode, newsize) =
case sizeval of
Just finitesize ->
let
newencode' accum [] = accum
newencode' accum (first : rest) =
newencode' ((accum * finitesize) + encodefunc first) rest
newdecode' accum 1 entropy = (decodefunc entropy : accum)
newdecode' _ 0 _ = []
newdecode' accum count entropy =
let
thisentropy = entropy `mod` finitesize
restentropy = entropy `quot` finitesize
this = decodefunc thisentropy
in
newdecode' (this : accum) (count - 1) restentropy
in
(newencode' 0, newdecode' [] len, Just (finitesize ^ len))
Nothing ->
let
newencode' = fromProdList . map encodefunc
newdecode' = map decodefunc . toProdList len
in
(newencode', newdecode', Nothing)
newindomain vals = length vals == fromInteger len && all indomainfunc vals
in
Encoding { encEncode = newencode, encDecode = newdecode,
encSize = newsize, encInDomain = newindomain }
set :: Ord ty => Encoding ty -> Encoding (Set ty)
set Encoding { encEncode = encodefunc, encDecode = decodefunc,
encSize = sizeval, encInDomain = indomainfunc } =
let
newEncode = Set.foldl (\n -> setBit n . fromInteger . encodefunc) 0
newDecode =
let
decode' out _ 0 = out
decode' out idx n
| testBit n 0 =
decode' (Set.insert (decodefunc idx) out) (idx + 1) (n `shiftR` 1)
| otherwise = decode' out (idx + 1) (n `shiftR` 1)
in
decode' Set.empty 0
newSize =
do
elems <- sizeval
return (2 ^ elems)
newInDomain = all indomainfunc . Set.toList
in
Encoding { encEncode = newEncode, encDecode = newDecode,
encSize = newSize, encInDomain = newInDomain }
hashSet :: (Hashable ty, Ord ty) =>
Encoding ty -> Encoding (HashSet ty)
hashSet Encoding { encEncode = encodefunc, encDecode = decodefunc,
encSize = sizeval, encInDomain = indomainfunc } =
let
newEncode =
HashSet.foldr (\elem n -> setBit n (fromInteger (encodefunc elem))) 0
newDecode =
let
decode' out _ 0 = out
decode' out idx n
| testBit n 0 =
decode' (HashSet.insert (decodefunc idx) out)
(idx + 1) (n `shiftR` 1)
| otherwise = decode' out (idx + 1) (n `shiftR` 1)
in
decode' HashSet.empty 0
newSize =
do
elems <- sizeval
return (2 ^ elems)
newInDomain = all indomainfunc . HashSet.toList
in
Encoding { encEncode = newEncode, encDecode = newDecode,
encSize = newSize, encInDomain = newInDomain }
seqCore :: Encoding ty -> ([ty] -> Integer, Integer -> [ty])
seqCore Encoding { encEncode = encodefunc, encDecode = decodefunc,
encSize = sizeval } =
case sizeval of
Just finitesize ->
let
newencodefunc =
let
foldfun accum = (((accum * finitesize) + 1) +) . encodefunc
in
foldl foldfun 0
newdecodefunc =
let
newdecodefunc' accum 0 = accum
newdecodefunc' accum num =
let
decoded = decodefunc ((num - 1) `mod` finitesize)
in
newdecodefunc' (decoded : accum) ((num - 1) `quot` finitesize)
in
newdecodefunc' []
in
(newencodefunc, newdecodefunc)
Nothing ->
let
newencodefunc [] = 0
newencodefunc (first : rest) =
let
insertUnary bin val =
let
encoded = encodefunc val
shifted = bin `shiftL` (fromInteger encoded)
in
shifted .|. ((2 ^ encoded) - 1)
foldfun accum val =
let
shifted = accum `shiftL` 1
in
insertUnary shifted val
initial = insertUnary 1 first
in
foldl foldfun initial rest
newdecodefunc 0 = []
newdecodefunc num =
let
leadingOnes :: Integer -> Integer
leadingOnes =
let
leadingOnes' count n
| testBit n 0 = leadingOnes' (count + 1) (n `shiftR` 1)
| otherwise = count
in
leadingOnes' 0
extractUnary bin =
let
unaryLen = leadingOnes bin
shifted = bin `shiftR` (fromInteger (unaryLen + 1))
decoded
| shifted /= 0 = decodefunc unaryLen
| otherwise = decodefunc (unaryLen - 1)
in
(decoded, shifted)
doDecode accum 0 = accum
doDecode accum bin =
let
(val, newbin) = extractUnary bin
in
doDecode (val : accum) newbin
in
doDecode [] num
in
(newencodefunc, newdecodefunc)
seq :: Encoding ty -> Encoding [ty]
seq enc @ Encoding { encInDomain = indomainfunc } =
let
(newEncode, newDecode) = seqCore enc
newInDomain = all indomainfunc
in
Encoding { encEncode = newEncode, encDecode = newDecode,
encSize = Nothing, encInDomain = newInDomain }
geometricSum :: Integer -> Integer -> Integer
geometricSum len 1 = len + 1
geometricSum len base = (1 - base ^ (len + 1)) `quot` (1 - base)
ilog :: Integer -> Integer -> Integer
ilog n = toInteger . integerLogBase' n
boundedSeqCore :: Integer -> Encoding ty -> ([ty] -> Integer, Integer -> [ty])
boundedSeqCore len Encoding { encEncode = encodefunc, encDecode = decodefunc,
encSize = sizeval } =
case sizeval of
Nothing ->
let
newencode [] = 0
newencode vals =
let
thislen = toInteger (length vals)
contentnum = fromProdList (map encodefunc vals)
in
(contentnum * len) + thislen
newdecode 0 = []
newdecode num =
let
adjusted = num - 1
(remainingEntropy, lengthEntropy) = adjusted `quotRem` len
thislen = lengthEntropy + 1
in
map decodefunc (toProdList thislen remainingEntropy)
in
(newencode, newdecode)
Just 0 -> (\[] -> 0, \0 -> [])
Just 1 -> (genericLength, flip genericReplicate (decodefunc 0))
Just finitesize ->
let
newencode [] = 0
newencode vals =
let
thislen = toInteger (length vals)
base = geometricSum (thislen - 1) finitesize
newencode' accum [] = accum
newencode' accum (first : rest) =
newencode' ((accum * finitesize) + encodefunc first) rest
in
base + (newencode' 0 (reverse vals))
newdecode 0 = []
newdecode num =
let
lowlen = ilog finitesize ((num * (finitesize - 1)) + 1) - 1
thislen = lowlen + 1
contentnum = num - (geometricSum lowlen finitesize)
newdecode' accum 1 entropy = (decodefunc entropy : accum)
newdecode' _ 0 _ = []
newdecode' accum count entropy =
let
thisentropy = entropy `mod` finitesize
restentropy = entropy `quot` finitesize
this = decodefunc thisentropy
in
newdecode' (this : accum) (count - 1) restentropy
in
reverse (newdecode' [] thislen contentnum)
in
(newencode, newdecode)
boundedSeq :: Integer
-> Encoding ty
-> Encoding [ty]
boundedSeq len enc @ Encoding { encSize = sizeval, encInDomain = indomainfunc } =
let
(newencode, newdecode) = boundedSeqCore len enc
newsize = case len of
0 -> Just 1
_ -> fmap (geometricSum len) sizeval
newindomain vals = length vals <= fromInteger len && all indomainfunc vals
in
Encoding { encEncode = newencode, encDecode = newdecode,
encSize = newsize, encInDomain = newindomain }
recursive :: (Encoding ty -> Encoding ty)
-> Encoding ty
recursive genfunc =
let
enc = Encoding { encEncode = encode (genfunc enc),
encDecode = decode (genfunc enc),
encInDomain = inDomain (genfunc enc),
encSize = Nothing }
in
enc
recursive2 :: ((Encoding ty1, Encoding ty2) -> Encoding ty1)
-> ((Encoding ty1, Encoding ty2) -> Encoding ty2)
-> (Encoding ty1, Encoding ty2)
recursive2 genfunc1 genfunc2 =
let
encs =
(Encoding { encEncode = encode (genfunc1 encs),
encDecode = decode (genfunc1 encs),
encInDomain = inDomain (genfunc1 encs),
encSize = Nothing },
Encoding { encEncode = encode (genfunc2 encs),
encDecode = decode (genfunc2 encs),
encInDomain = inDomain (genfunc2 encs),
encSize = Nothing })
in
encs
recursive3 :: ((Encoding ty1, Encoding ty2, Encoding ty3) -> Encoding ty1)
-> ((Encoding ty1, Encoding ty2, Encoding ty3) -> Encoding ty2)
-> ((Encoding ty1, Encoding ty2, Encoding ty3) -> Encoding ty3)
-> (Encoding ty1, Encoding ty2, Encoding ty3)
recursive3 genfunc1 genfunc2 genfunc3 =
let
encs =
(Encoding { encEncode = encode (genfunc1 encs),
encDecode = decode (genfunc1 encs),
encInDomain = inDomain (genfunc1 encs),
encSize = Nothing },
Encoding { encEncode = encode (genfunc2 encs),
encDecode = decode (genfunc2 encs),
encInDomain = inDomain (genfunc2 encs),
encSize = Nothing },
Encoding { encEncode = encode (genfunc3 encs),
encDecode = decode (genfunc3 encs),
encInDomain = inDomain (genfunc3 encs),
encSize = Nothing })
in
encs
recursive4 :: ((Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4) ->
Encoding ty1)
-> ((Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4) ->
Encoding ty2)
-> ((Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4) ->
Encoding ty3)
-> ((Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4) ->
Encoding ty4)
-> (Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4)
recursive4 genfunc1 genfunc2 genfunc3 genfunc4 =
let
encs =
(Encoding { encEncode = encode (genfunc1 encs),
encDecode = decode (genfunc1 encs),
encInDomain = inDomain (genfunc1 encs),
encSize = Nothing },
Encoding { encEncode = encode (genfunc2 encs),
encDecode = decode (genfunc2 encs),
encInDomain = inDomain (genfunc2 encs),
encSize = Nothing },
Encoding { encEncode = encode (genfunc3 encs),
encDecode = decode (genfunc3 encs),
encInDomain = inDomain (genfunc3 encs),
encSize = Nothing },
Encoding { encEncode = encode (genfunc4 encs),
encDecode = decode (genfunc4 encs),
encInDomain = inDomain (genfunc4 encs),
encSize = Nothing })
in
encs
recursive5 :: ((Encoding ty1, Encoding ty2, Encoding ty3,
Encoding ty4, Encoding ty5) -> Encoding ty1)
-> ((Encoding ty1, Encoding ty2, Encoding ty3,
Encoding ty4, Encoding ty5) -> Encoding ty2)
-> ((Encoding ty1, Encoding ty2, Encoding ty3,
Encoding ty4, Encoding ty5) -> Encoding ty3)
-> ((Encoding ty1, Encoding ty2, Encoding ty3,
Encoding ty4, Encoding ty5) -> Encoding ty4)
-> ((Encoding ty1, Encoding ty2, Encoding ty3,
Encoding ty4, Encoding ty5) -> Encoding ty5)
-> (Encoding ty1, Encoding ty2, Encoding ty3,
Encoding ty4, Encoding ty5)
recursive5 genfunc1 genfunc2 genfunc3 genfunc4 genfunc5 =
let
encs =
(Encoding { encEncode = encode (genfunc1 encs),
encDecode = decode (genfunc1 encs),
encInDomain = inDomain (genfunc1 encs),
encSize = Nothing },
Encoding { encEncode = encode (genfunc2 encs),
encDecode = decode (genfunc2 encs),
encInDomain = inDomain (genfunc2 encs),
encSize = Nothing },
Encoding { encEncode = encode (genfunc3 encs),
encDecode = decode (genfunc3 encs),
encInDomain = inDomain (genfunc3 encs),
encSize = Nothing },
Encoding { encEncode = encode (genfunc4 encs),
encDecode = decode (genfunc4 encs),
encInDomain = inDomain (genfunc4 encs),
encSize = Nothing },
Encoding { encEncode = encode (genfunc5 encs),
encDecode = decode (genfunc5 encs),
encInDomain = inDomain (genfunc5 encs),
encSize = Nothing })
in
encs
recursive6 :: ((Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4,
Encoding ty5, Encoding ty6) -> Encoding ty1)
-> ((Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4,
Encoding ty5, Encoding ty6) -> Encoding ty2)
-> ((Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4,
Encoding ty5, Encoding ty6) -> Encoding ty3)
-> ((Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4,
Encoding ty5, Encoding ty6) -> Encoding ty4)
-> ((Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4,
Encoding ty5, Encoding ty6) -> Encoding ty5)
-> ((Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4,
Encoding ty5, Encoding ty6) -> Encoding ty6)
-> (Encoding ty1, Encoding ty2, Encoding ty3,
Encoding ty4, Encoding ty5, Encoding ty6)
recursive6 genfunc1 genfunc2 genfunc3 genfunc4 genfunc5 genfunc6 =
let
encs =
(Encoding { encEncode = encode (genfunc1 encs),
encDecode = decode (genfunc1 encs),
encInDomain = inDomain (genfunc1 encs),
encSize = Nothing },
Encoding { encEncode = encode (genfunc2 encs),
encDecode = decode (genfunc2 encs),
encInDomain = inDomain (genfunc2 encs),
encSize = Nothing },
Encoding { encEncode = encode (genfunc3 encs),
encDecode = decode (genfunc3 encs),
encInDomain = inDomain (genfunc3 encs),
encSize = Nothing },
Encoding { encEncode = encode (genfunc4 encs),
encDecode = decode (genfunc4 encs),
encInDomain = inDomain (genfunc4 encs),
encSize = Nothing },
Encoding { encEncode = encode (genfunc5 encs),
encDecode = decode (genfunc5 encs),
encInDomain = inDomain (genfunc5 encs),
encSize = Nothing },
Encoding { encEncode = encode (genfunc6 encs),
encDecode = decode (genfunc6 encs),
encInDomain = inDomain (genfunc6 encs),
encSize = Nothing })
in
encs
recursive7 :: ((Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4,
Encoding ty5, Encoding ty6, Encoding ty7) -> Encoding ty1)
-> ((Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4,
Encoding ty5, Encoding ty6, Encoding ty7) -> Encoding ty2)
-> ((Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4,
Encoding ty5, Encoding ty6, Encoding ty7) -> Encoding ty3)
-> ((Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4,
Encoding ty5, Encoding ty6, Encoding ty7) -> Encoding ty4)
-> ((Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4,
Encoding ty5, Encoding ty6, Encoding ty7) -> Encoding ty5)
-> ((Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4,
Encoding ty5, Encoding ty6, Encoding ty7) -> Encoding ty6)
-> ((Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4,
Encoding ty5, Encoding ty6, Encoding ty7) -> Encoding ty7)
-> (Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4,
Encoding ty5, Encoding ty6, Encoding ty7)
recursive7 genfunc1 genfunc2 genfunc3 genfunc4 genfunc5 genfunc6 genfunc7 =
let
encs =
(Encoding { encEncode = encode (genfunc1 encs),
encDecode = decode (genfunc1 encs),
encInDomain = inDomain (genfunc1 encs),
encSize = Nothing },
Encoding { encEncode = encode (genfunc2 encs),
encDecode = decode (genfunc2 encs),
encInDomain = inDomain (genfunc2 encs),
encSize = Nothing },
Encoding { encEncode = encode (genfunc3 encs),
encDecode = decode (genfunc3 encs),
encInDomain = inDomain (genfunc3 encs),
encSize = Nothing },
Encoding { encEncode = encode (genfunc4 encs),
encDecode = decode (genfunc4 encs),
encInDomain = inDomain (genfunc4 encs),
encSize = Nothing },
Encoding { encEncode = encode (genfunc5 encs),
encDecode = decode (genfunc5 encs),
encInDomain = inDomain (genfunc5 encs),
encSize = Nothing },
Encoding { encEncode = encode (genfunc6 encs),
encDecode = decode (genfunc6 encs),
encInDomain = inDomain (genfunc6 encs),
encSize = Nothing },
Encoding { encEncode = encode (genfunc7 encs),
encDecode = decode (genfunc7 encs),
encInDomain = inDomain (genfunc7 encs),
encSize = Nothing })
in
encs
recursive8 :: ((Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4,
Encoding ty5, Encoding ty6, Encoding ty7, Encoding ty8) ->
Encoding ty1)
-> ((Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4,
Encoding ty5, Encoding ty6, Encoding ty7, Encoding ty8) ->
Encoding ty2)
-> ((Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4,
Encoding ty5, Encoding ty6, Encoding ty7, Encoding ty8) ->
Encoding ty3)
-> ((Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4,
Encoding ty5, Encoding ty6, Encoding ty7, Encoding ty8) ->
Encoding ty4)
-> ((Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4,
Encoding ty5, Encoding ty6, Encoding ty7, Encoding ty8) ->
Encoding ty5)
-> ((Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4,
Encoding ty5, Encoding ty6, Encoding ty7, Encoding ty8) ->
Encoding ty6)
-> ((Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4,
Encoding ty5, Encoding ty6, Encoding ty7, Encoding ty8) ->
Encoding ty7)
-> ((Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4,
Encoding ty5, Encoding ty6, Encoding ty7, Encoding ty8) ->
Encoding ty8)
-> (Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4,
Encoding ty5, Encoding ty6, Encoding ty7, Encoding ty8)
recursive8 genfunc1 genfunc2 genfunc3 genfunc4 genfunc5 genfunc6 genfunc7 genfunc8 =
let
encs =
(Encoding { encEncode = encode (genfunc1 encs),
encDecode = decode (genfunc1 encs),
encInDomain = inDomain (genfunc1 encs),
encSize = Nothing },
Encoding { encEncode = encode (genfunc2 encs),
encDecode = decode (genfunc2 encs),
encInDomain = inDomain (genfunc2 encs),
encSize = Nothing },
Encoding { encEncode = encode (genfunc3 encs),
encDecode = decode (genfunc3 encs),
encInDomain = inDomain (genfunc3 encs),
encSize = Nothing },
Encoding { encEncode = encode (genfunc4 encs),
encDecode = decode (genfunc4 encs),
encInDomain = inDomain (genfunc4 encs),
encSize = Nothing },
Encoding { encEncode = encode (genfunc5 encs),
encDecode = decode (genfunc5 encs),
encInDomain = inDomain (genfunc5 encs),
encSize = Nothing },
Encoding { encEncode = encode (genfunc6 encs),
encDecode = decode (genfunc6 encs),
encInDomain = inDomain (genfunc6 encs),
encSize = Nothing },
Encoding { encEncode = encode (genfunc7 encs),
encDecode = decode (genfunc7 encs),
encInDomain = inDomain (genfunc7 encs),
encSize = Nothing },
Encoding { encEncode = encode (genfunc8 encs),
encDecode = decode (genfunc8 encs),
encInDomain = inDomain (genfunc8 encs),
encSize = Nothing })
in
encs
recursive9 :: ((Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4,
Encoding ty5, Encoding ty6, Encoding ty7,
Encoding ty8, Encoding ty9) -> Encoding ty1)
-> ((Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4,
Encoding ty5, Encoding ty6, Encoding ty7,
Encoding ty8, Encoding ty9) -> Encoding ty2)
-> ((Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4,
Encoding ty5, Encoding ty6, Encoding ty7,
Encoding ty8, Encoding ty9) -> Encoding ty3)
-> ((Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4,
Encoding ty5, Encoding ty6, Encoding ty7,
Encoding ty8, Encoding ty9) -> Encoding ty4)
-> ((Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4,
Encoding ty5, Encoding ty6, Encoding ty7,
Encoding ty8, Encoding ty9) -> Encoding ty5)
-> ((Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4,
Encoding ty5, Encoding ty6, Encoding ty7,
Encoding ty8, Encoding ty9) -> Encoding ty6)
-> ((Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4,
Encoding ty5, Encoding ty6, Encoding ty7,
Encoding ty8, Encoding ty9) -> Encoding ty7)
-> ((Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4,
Encoding ty5, Encoding ty6, Encoding ty7,
Encoding ty8, Encoding ty9) -> Encoding ty8)
-> ((Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4,
Encoding ty5, Encoding ty6, Encoding ty7,
Encoding ty8, Encoding ty9) -> Encoding ty9)
-> (Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4, Encoding ty5,
Encoding ty6, Encoding ty7, Encoding ty8, Encoding ty9)
recursive9 genfunc1 genfunc2 genfunc3 genfunc4 genfunc5
genfunc6 genfunc7 genfunc8 genfunc9 =
let
encs =
(Encoding { encEncode = encode (genfunc1 encs),
encDecode = decode (genfunc1 encs),
encInDomain = inDomain (genfunc1 encs),
encSize = Nothing },
Encoding { encEncode = encode (genfunc2 encs),
encDecode = decode (genfunc2 encs),
encInDomain = inDomain (genfunc2 encs),
encSize = Nothing },
Encoding { encEncode = encode (genfunc3 encs),
encDecode = decode (genfunc3 encs),
encInDomain = inDomain (genfunc3 encs),
encSize = Nothing },
Encoding { encEncode = encode (genfunc4 encs),
encDecode = decode (genfunc4 encs),
encInDomain = inDomain (genfunc4 encs),
encSize = Nothing },
Encoding { encEncode = encode (genfunc5 encs),
encDecode = decode (genfunc5 encs),
encInDomain = inDomain (genfunc5 encs),
encSize = Nothing },
Encoding { encEncode = encode (genfunc6 encs),
encDecode = decode (genfunc6 encs),
encInDomain = inDomain (genfunc6 encs),
encSize = Nothing },
Encoding { encEncode = encode (genfunc7 encs),
encDecode = decode (genfunc7 encs),
encInDomain = inDomain (genfunc7 encs),
encSize = Nothing },
Encoding { encEncode = encode (genfunc8 encs),
encDecode = decode (genfunc8 encs),
encInDomain = inDomain (genfunc8 encs),
encSize = Nothing },
Encoding { encEncode = encode (genfunc9 encs),
encDecode = decode (genfunc9 encs),
encInDomain = inDomain (genfunc9 encs),
encSize = Nothing })
in
encs
recursive10 :: ((Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4,
Encoding ty5, Encoding ty6, Encoding ty7, Encoding ty8,
Encoding ty9, Encoding ty10) -> Encoding ty1)
-> ((Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4,
Encoding ty5, Encoding ty6, Encoding ty7, Encoding ty8,
Encoding ty9, Encoding ty10) -> Encoding ty2)
-> ((Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4,
Encoding ty5, Encoding ty6, Encoding ty7, Encoding ty8,
Encoding ty9, Encoding ty10) -> Encoding ty3)
-> ((Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4,
Encoding ty5, Encoding ty6, Encoding ty7, Encoding ty8,
Encoding ty9, Encoding ty10) -> Encoding ty4)
-> ((Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4,
Encoding ty5, Encoding ty6, Encoding ty7, Encoding ty8,
Encoding ty9, Encoding ty10) -> Encoding ty5)
-> ((Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4,
Encoding ty5, Encoding ty6, Encoding ty7, Encoding ty8,
Encoding ty9, Encoding ty10) -> Encoding ty6)
-> ((Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4,
Encoding ty5, Encoding ty6, Encoding ty7, Encoding ty8,
Encoding ty9, Encoding ty10) -> Encoding ty7)
-> ((Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4,
Encoding ty5, Encoding ty6, Encoding ty7, Encoding ty8,
Encoding ty9, Encoding ty10) -> Encoding ty8)
-> ((Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4,
Encoding ty5, Encoding ty6, Encoding ty7, Encoding ty8,
Encoding ty9, Encoding ty10) -> Encoding ty9)
-> ((Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4,
Encoding ty5, Encoding ty6, Encoding ty7, Encoding ty8,
Encoding ty9, Encoding ty10) -> Encoding ty10)
-> (Encoding ty1, Encoding ty2, Encoding ty3, Encoding ty4,
Encoding ty5, Encoding ty6, Encoding ty7, Encoding ty8,
Encoding ty9, Encoding ty10)
recursive10 genfunc1 genfunc2 genfunc3 genfunc4 genfunc5
genfunc6 genfunc7 genfunc8 genfunc9 genfunc10 =
let
encs =
(Encoding { encEncode = encode (genfunc1 encs),
encDecode = decode (genfunc1 encs),
encInDomain = inDomain (genfunc1 encs),
encSize = Nothing },
Encoding { encEncode = encode (genfunc2 encs),
encDecode = decode (genfunc2 encs),
encInDomain = inDomain (genfunc2 encs),
encSize = Nothing },
Encoding { encEncode = encode (genfunc3 encs),
encDecode = decode (genfunc3 encs),
encInDomain = inDomain (genfunc3 encs),
encSize = Nothing },
Encoding { encEncode = encode (genfunc4 encs),
encDecode = decode (genfunc4 encs),
encInDomain = inDomain (genfunc4 encs),
encSize = Nothing },
Encoding { encEncode = encode (genfunc5 encs),
encDecode = decode (genfunc5 encs),
encInDomain = inDomain (genfunc5 encs),
encSize = Nothing },
Encoding { encEncode = encode (genfunc6 encs),
encDecode = decode (genfunc6 encs),
encInDomain = inDomain (genfunc6 encs),
encSize = Nothing },
Encoding { encEncode = encode (genfunc7 encs),
encDecode = decode (genfunc7 encs),
encInDomain = inDomain (genfunc7 encs),
encSize = Nothing },
Encoding { encEncode = encode (genfunc8 encs),
encDecode = decode (genfunc8 encs),
encInDomain = inDomain (genfunc8 encs),
encSize = Nothing },
Encoding { encEncode = encode (genfunc9 encs),
encDecode = decode (genfunc9 encs),
encInDomain = inDomain (genfunc9 encs),
encSize = Nothing },
Encoding { encEncode = encode (genfunc10 encs),
encDecode = decode (genfunc10 encs),
encInDomain = inDomain (genfunc10 encs),
encSize = Nothing })
in
encs