{-# LANGUAGE ScopedTypeVariables, TypeFamilies, ExistentialQuantification, ImplicitParams, DefaultSignatures #-}
module Language.Format (
module Language.Parser,
Gen.Generic,
SerialStreamType(..),SerialStream(..),Serializable(..),Format(..),Builder,bytesBuilder,chunkBuilder,serialize,serial,stringBytes,
defaultEncode,defaultDatum,encodeFree,encodeCofree,datumFree,datumCofree,
word8,Word8,Word16,Word32,Word64,LittleEndian(..),encodeAlt,FormatAlt(..),datumOf,getChunk,
writeSerial,readFormat,writeHSerial,readHFormat,
runConnection,runConnection_,send,receive,
Proxy(..),exchange,sending,
coerceEncode,coerceDatum
) where
import Data.Bits (shiftR,shiftL,xor)
import Data.ByteString.Lazy.Builder
import Data.Word
import Definitive
import Language.Parser hiding (uncons)
import qualified Control.DeepSeq as DeepSeq
import qualified Data.ByteString.Lazy as BS
import qualified Data.ByteString.Lazy.UTF8 as UTF8
import qualified Data.Monoid as M
import qualified Prelude as P
import System.IO (hFlush,withFile,IOMode(..))
import GHC.IO.Handle (hClose)
import Unsafe.Coerce
import Foreign.Ptr (castPtr)
import Foreign.Storable (peek,poke)
import Foreign.Marshal.Alloc (alloca)
import qualified GHC.Generics as Gen
class ParseStreamType s => SerialStreamType s where
type StreamBuilder s :: *
class (SerialStreamType stream,ParseStream stream,StreamChar stream ~ Word8, Monoid (StreamBuilder stream)) => SerialStream stream where
encodeByte :: Proxy stream -> Word8 -> StreamBuilder stream
toSerialStream :: StreamBuilder stream -> stream
instance ParseStreamType Bytes where
type StreamToken Bytes = Word8
type StreamChar Bytes = Word8
instance ParseStream Bytes where
tokenPayload _ c = c
instance SerialStreamType Bytes where
type StreamBuilder Bytes = Builder
instance SerialStream Bytes where
encodeByte _ = word8
toSerialStream = toLazyByteString
class SerialStream stream => Serializable stream t where
encode :: Proxy stream -> t -> StreamBuilder stream
default encode :: (Gen.Generic t, GenSerializable stream (Gen.Rep t)) => Proxy stream -> t -> StreamBuilder stream
encode = defaultEncode
class Serializable stream t => Format stream t where
datum :: Parser stream t
default datum :: (Gen.Generic t, GenFormat stream (Gen.Rep t)) => Parser stream t
datum = defaultDatum
defaultEncode :: (Gen.Generic t, GenSerializable stream (Gen.Rep t)) => Proxy stream -> t -> StreamBuilder stream
defaultEncode p a = genEncode p (Gen.from a)
defaultDatum :: (Gen.Generic t, GenFormat stream (Gen.Rep t)) => Parser stream t
defaultDatum = Gen.to <$> genDatum
class SerialStream stream => GenSerializable stream f where
genEncode :: Proxy stream -> f a -> StreamBuilder stream
class GenSerializable stream f => GenFormat stream f where
genDatum :: Parser stream (f a)
class GenAlt f where
altTotal :: f a -> Int
altTotal _ = 1
class (GenAlt f,GenSerializable stream f) => GenSerAlt stream f where
altEncode :: Proxy stream -> f a -> Int -> StreamBuilder stream
altEncode p fa n = encode p n + genEncode p fa
class (GenSerAlt stream f,GenFormat stream f) => GenFormatAlt stream f where
altDatum :: Int -> Parser stream (f a)
altDatum 0 = genDatum
altDatum _ = zero
instance GenAlt Gen.V1
instance SerialStream stream => GenSerializable stream Gen.V1 where genEncode = undefined
instance SerialStream stream => GenFormat stream Gen.V1 where genDatum = undefined
instance SerialStream stream => GenSerAlt stream Gen.V1
instance SerialStream stream => GenFormatAlt stream Gen.V1
instance GenAlt Gen.U1
instance SerialStream stream => GenSerializable stream Gen.U1 where genEncode _ = zero
instance SerialStream stream => GenFormat stream Gen.U1 where genDatum = pure Gen.U1
instance SerialStream stream => GenSerAlt stream Gen.U1
instance SerialStream stream => GenFormatAlt stream Gen.U1
instance GenAlt (Gen.K1 i c)
instance (SerialStream stream, Serializable stream t) => GenSerializable stream (Gen.K1 i t) where
genEncode p (Gen.K1 t) = encode p t
instance (SerialStream stream, Format stream t) => GenFormat stream (Gen.K1 i t) where
genDatum = Gen.K1 <$> datum
instance (SerialStream stream, Serializable stream t) => GenSerAlt stream (Gen.K1 i t)
instance (SerialStream stream, Format stream t) => GenFormatAlt stream (Gen.K1 i t)
instance GenAlt f => GenAlt (Gen.M1 i t f) where altTotal (Gen.M1 fa) = altTotal fa
instance (SerialStream stream, GenSerializable stream f) => GenSerializable stream (Gen.M1 i t f) where
genEncode p (Gen.M1 x) = genEncode p x
instance (SerialStream stream, GenFormat stream f) => GenFormat stream (Gen.M1 i t f) where
genDatum = Gen.M1 <$> genDatum
instance (SerialStream stream, GenSerAlt stream f) => GenSerAlt stream (Gen.M1 i t f) where
altEncode p (Gen.M1 fa) = altEncode p fa
instance (SerialStream stream, GenFormatAlt stream f) => GenFormatAlt stream (Gen.M1 i t f) where
altDatum n = Gen.M1 <$> altDatum n
instance GenAlt (f Gen.:*: g)
instance (GenSerializable stream f, GenSerializable stream g) => GenSerializable stream (f Gen.:*: g) where
genEncode p (fa Gen.:*: ga) = genEncode p fa + genEncode p ga
instance (GenFormat stream f, GenFormat stream g) => GenFormat stream (f Gen.:*: g) where
genDatum = liftA2 (Gen.:*:) genDatum genDatum
instance (GenSerializable stream f,GenSerializable stream g) => GenSerAlt stream (f Gen.:*: g)
instance (GenFormat stream f, GenFormat stream g) => GenFormatAlt stream (f Gen.:*: g) where
instance (GenAlt f,GenAlt g) => GenAlt (f Gen.:+: g) where
altTotal = \_ -> tot
where tot = altTotal (undefined :: f a) + altTotal (undefined :: g a)
instance (GenSerAlt stream f,GenSerAlt stream g) => GenSerializable stream (f Gen.:+: g) where
genEncode p (Gen.L1 fa) = altEncode p fa 0
genEncode p (Gen.R1 ga) = altEncode p ga (altTotal (undefined :: f a))
instance (GenFormatAlt stream f,GenFormatAlt stream g) => GenFormat stream (f Gen.:+: g) where
genDatum = datum >>= altDatum
instance (GenSerAlt stream f,GenSerAlt stream g) => GenSerAlt stream (f Gen.:+: g) where
altEncode p (Gen.L1 f) n = altEncode p f n
altEncode p (Gen.R1 g) n = altEncode p g (altTotal (undefined :: f a)+n)
instance (GenFormatAlt stream f,GenFormatAlt stream g) => GenFormatAlt stream (f Gen.:+: g) where
altDatum = \n -> if n < tot then Gen.L1 <$> altDatum n else Gen.R1 <$> altDatum (n - tot)
where tot = altTotal (undefined :: f a)
writeHSerial :: Serializable Bytes a => Handle -> a -> IO ()
writeHSerial h a = ser`DeepSeq.deepseq`writeHBytes h ser
where ser = serialize a
writeSerial :: Serializable Bytes a => String -> a -> IO ()
writeSerial h a = ser`DeepSeq.deepseq`writeBytes h ser
where ser = serialize a
readHFormat :: Format Bytes a => Handle -> IO a
readHFormat h = maybe (error "Coudn't parse format") return . matches Just datum . DeepSeq.force =<< readHBytes h
readFormat :: Format Bytes a => String -> IO a
readFormat f = withFile f ReadMode $ readHFormat
coerceEncode :: forall stream t t'. Serializable stream t => (t -> t') -> (Proxy stream -> t' -> StreamBuilder stream)
coerceEncode _ = unsafeCoerce (encode :: Proxy stream -> t -> StreamBuilder stream)
coerceDatum :: forall stream t t'. Format stream t => (t -> t') -> (Parser stream t')
coerceDatum _ = unsafeCoerce (datum :: Parser stream t)
serialize :: forall stream t. Serializable stream t => t -> stream
serialize = toSerialStream . encode (Proxy :: Proxy stream)
serial :: (Format stream t,Serializable stream t') => Traversal t t' stream stream
serial = prism (datum^.from parser & \f a -> map snd (foldr (const . Right) (Left a) (f a))) (const serialize)
bytesBuilder :: Bytes:<->:Builder
bytesBuilder = iso lazyByteString toLazyByteString
chunkBuilder :: Chunk:<->:Builder
chunkBuilder = iso byteString (by chunk.toLazyByteString)
stringBytes :: String -> Bytes
stringBytes s = foldMap (encode (Proxy :: Proxy Bytes)) s^..bytesBuilder
encodeAlt :: Serializable stream a => Proxy stream -> Word8 -> a -> StreamBuilder stream
encodeAlt p n a = encodeByte p n + encode p a
data FormatAlt stream a = forall b. Format stream b => FormatAlt (b -> a)
datumOf :: SerialStream stream => [FormatAlt stream a] -> Parser stream a
datumOf l = datum >>= \x -> case drop (fromIntegral (x :: Word8)) l of
(FormatAlt h:_) -> h<$>datum
_ -> zero
getChunk :: Int -> Parser Bytes Chunk
getChunk sz = splitAt sz<$>remaining >>= \(h,t) -> guard (bytesSize h == sz) >> (by chunk h <$ runStreamState (put t))
runConnection :: (MonadIO io,Monoid m) =>
(a -> m)
-> Bool
-> Handle
-> ((?write :: Bytes -> IO ()) => ParserT Bytes io a)
-> io m
runConnection x close h srv = do
bs <- liftIO (readHBytes h)
let ?write = \bs' -> writeHChunk h (bs'^.chunk) >> hFlush h
matchesT x srv bs <* liftIO (when close (hClose h))
runConnection_ :: MonadIO io => Bool -> Handle -> ((?write :: Bytes -> IO ()) => ParserT Bytes io a) -> io ()
runConnection_ = runConnection (const ())
send :: (Serializable Bytes t, MonadIO m, ?write :: Bytes -> IO ()) => t -> m ()
send x = liftIO (?write (serialize x))
receive :: (Format stream t,Monad m) => ParserT stream m t
receive = generalize datum
instance SerialStream stream => Serializable stream (Proxy a) where encode Proxy = zero
instance SerialStream stream => Format stream (Proxy a) where datum = return Proxy
exchange :: (MonadIO m,?write :: Bytes -> IO (),Format stream a,Serializable Bytes b) => (Proxy a -> b) -> ParserT stream m a
exchange f = do
send (f Proxy)
receive
sending :: (MonadIO m,?write :: Bytes -> IO (),Serializable Bytes a) => Proxy a -> a -> m ()
sending _ = send
wordToFloat :: Word32 -> Float
wordToFloat w = by thunk $ alloca $ \p -> poke p w >> peek (castPtr p)
floatToWord :: Float -> Word32
floatToWord w = by thunk $ alloca $ \p -> poke p w >> peek (castPtr p)
wordToDouble :: Word64 -> Double
wordToDouble w = by thunk $ alloca $ \p -> poke p w >> peek (castPtr p)
doubleToWord :: Double -> Word64
doubleToWord w = by thunk $ alloca $ \p -> poke p w >> peek (castPtr p)
newtype LittleEndian t = LittleEndian { fromLittleEndian :: t }
instance Semigroup Word8 ; instance Monoid Word8
instance Semigroup Word16 ; instance Monoid Word16
instance Semigroup Word32 ; instance Monoid Word32
instance Semigroup Word64 ; instance Monoid Word64
instance Semiring Word8 where (*) = (P.*)
instance Ring Word8 where one = 1
instance Semiring Word16 where (*) = (P.*)
instance Ring Word16 where one = 1
instance Semiring Word32 where (*) = (P.*)
instance Ring Word32 where one = 1
instance Semiring Word64 where (*) = (P.*)
instance Ring Word64 where one = 1
instance Disjonctive Word8 where
negate = P.negate ; (-) = (P.-)
instance Disjonctive Word16 where
negate = P.negate ; (-) = (P.-)
instance Disjonctive Word32 where
negate = P.negate ; (-) = (P.-)
instance Disjonctive Word64 where
negate = P.negate ; (-) = (P.-)
instance Semigroup Builder where (+) = M.mappend
instance Monoid Builder where zero = M.mempty
instance Serializable Bytes Char where
encode _ = charUtf8
instance Format Bytes Char where
datum = runStreamState (gets UTF8.uncons) >>= \x -> case x of
Just (c,t) -> c <$ runStreamState (put t)
Nothing -> zero
instance SerialStream stream => Serializable stream Word8 where
encode = encodeByte
instance SerialStream stream => Format stream Word8 where
datum = token
instance Serializable Bytes Bytes where
encode p b = encode p (fromIntegral (BS.length b) :: Int) + b^.bytesBuilder
instance Format Bytes Bytes where
datum = do
sz <- datum
x <- remaining
let (h,t) = splitAt sz x
h <$ runStreamState (put t)
instance Serializable Bytes Word16 where
encode _ = word16BE
instance Format Bytes Word16 where
datum = mkW16 <$> doTimes 2 datum
where mkW16 l = sum $ zipWith shiftL (map fi l) [8,0]
fi = fromIntegral :: Word8 -> Word16
instance Serializable Bytes (LittleEndian Word16) where
encode _ = word16LE . fromLittleEndian
instance Format Bytes (LittleEndian Word16) where
datum = LittleEndian . mkW16 <$> doTimes 2 datum
where mkW16 l = sum $ zipWith shiftL (map fi l) [0,8]
fi = fromIntegral :: Word8 -> Word16
instance Serializable Bytes Word32 where
encode _ = word32BE
instance Format Bytes Word32 where
datum = mkW32 <$> doTimes 4 datum
where mkW32 l = sum $ zipWith shiftL (map fi l) [24,16,8,0]
fi = fromIntegral :: Word8 -> Word32
instance Serializable Bytes (LittleEndian Word32) where
encode _ = word32LE . fromLittleEndian
instance Format Bytes (LittleEndian Word32) where
datum = LittleEndian . mkW32 <$> doTimes 4 datum
where mkW32 l = sum $ zipWith shiftL (map fi l) [0,8,16,24]
fi = fromIntegral :: Word8 -> Word32
instance Serializable Bytes Word64 where
encode _ = word64BE
instance Format Bytes Word64 where
datum = mkW64 <$> doTimes 8 datum
where mkW64 l = sum $ zipWith shiftL (map fi l) [56,48,40,32,24,16,8,0]
fi = fromIntegral :: Word8 -> Word64
instance Serializable Bytes (LittleEndian Word64) where
encode _ = word64LE . fromLittleEndian
instance Format Bytes (LittleEndian Word64) where
datum = LittleEndian . mkW64 <$> doTimes 8 datum
where mkW64 l = sum $ zipWith shiftL (map fi l) [0,8,16,24,32,40,48,56]
fi = fromIntegral :: Word8 -> Word64
instance SerialStream stream => Serializable stream Int where
encode p n = foldMap (encodeByte p) bytes'
where bytes = map fromIntegral $ takeWhile (>0) $ iterate (`shiftR`8) n
bytes' = case bytes of
[] -> [0]
[h] | h < 0x80 -> [h]
_ -> (0x80 `xor` size bytes):bytes
instance SerialStream stream => Format stream Int where
datum = datum >>= \(n :: Word8) ->
if n < 0x80 then return (fromIntegral n)
else do
bytes <- sequence (datum <$ [1..(n`xor`0x80)])
return $ sum (zipWith shiftL (map (fromIntegral :: Word8 -> Int) bytes) [0,8..])
instance Serializable Bytes Float where encode p = encode p . floatToWord
instance Format Bytes Float where datum = wordToFloat<$>datum
instance Serializable Bytes Double where encode p = encode p . doubleToWord
instance Format Bytes Double where datum = wordToDouble<$>datum
instance SerialStream stream => Serializable stream Bool where
encode p = encodeByte p . fromIntegral . fromEnum
instance SerialStream stream => Format stream Bool where
datum = toEnum . (fromIntegral :: Word8 -> Int) <$> datum
instance SerialStream stream => Serializable stream () where encode _ = zero
instance SerialStream stream => Format stream () where datum = unit
instance SerialStream stream => Serializable stream Integer where
encode p n = encode p s + foldMap (encodeByte p . fromIntegral) (take s l)
where l = iterate (`shiftR`8) (if n>=0 then n else (-n))
s = length (takeWhile (/=0) l)
instance SerialStream stream => Format stream Integer where
datum = do
n <- datum
doTimes n datum <&> sum . zipWith (\sh b -> fromIntegral (b :: Word8)`shiftL`sh) [0,8..]
instance Serializable stream a => Serializable stream (Maybe a) where
encode p Nothing = encodeAlt p 0 ()
encode p (Just a) = encodeAlt p 1 a
instance Format stream a => Format stream (Maybe a) where
datum = datumOf [FormatAlt (\() -> Nothing), FormatAlt Just]
instance Serializable stream a => Serializable stream [a] where
encode p l = encode p (length l) + foldMap (\x -> encode p x) l
instance Format stream a => Format stream [a] where
datum = datum >>= \n -> doTimes n datum
encodeFree :: (Serializable stream (Forest f a),Serializable stream a) => Proxy stream -> Free f a -> StreamBuilder stream
encodeFree p (Pure s) = encodeAlt p 0 s
encodeFree p (Join f) = encodeAlt p 1 f
instance Serializable stream a => Serializable stream (Free Maybe a) where encode = encodeFree
instance Serializable stream a => Serializable stream (Free [] a) where encode = encodeFree
instance (Serializable stream k,Serializable stream a) => Serializable stream (Free (Map k) a) where encode = encodeFree
instance Serializable stream a => Serializable stream (Cofree Maybe a) where encode = encodeCofree
instance Serializable stream a => Serializable stream (Cofree [] a) where encode = encodeCofree
instance (Serializable stream k,Serializable stream a) => Serializable stream (Cofree (Map k) a) where encode = encodeCofree
datumFree :: (Format stream (Forest f a),Format stream a) => Parser stream (Free f a)
datumFree = datumOf [FormatAlt Pure,FormatAlt Join]
instance Format stream a => Format stream (Free Maybe a) where datum = datumFree
instance Format stream a => Format stream (Free [] a) where datum = datumFree
instance (Ord k,Format stream k,Format stream a) => Format stream (Free (Map k) a) where datum = datumFree
instance Format stream a => Format stream (Cofree Maybe a) where datum = datumCofree
instance Format stream a => Format stream (Cofree [] a) where datum = datumCofree
instance (Ord k,Format stream k,Format stream a) => Format stream (Cofree (Map k) a) where datum = datumCofree
encodeCofree :: (Serializable stream (Coforest f a),Serializable stream a) => Proxy stream -> Cofree f a -> StreamBuilder stream
encodeCofree p (Step a fc) = encode p (a,fc)
datumCofree :: (Format stream (Coforest f a),Format stream a) => Parser stream (Cofree f a)
datumCofree = uncurry Step<$>datum
instance Serializable stream (f (g a)) => Serializable stream ((f:.:g) a) where
encode = coerceEncode Compose
instance Format stream (f (g a)) => Format stream ((f:.:g) a) where
datum = coerceDatum Compose
instance (Serializable stream k,Serializable stream a) => Serializable stream (Map k a) where
encode p m = encode p (m^.keyed & toList)
instance (Ord k,Format stream k,Format stream a) => Format stream (Map k a) where
datum = datum <&> fromAList
instance (Serializable stream k,Serializable stream a) => Serializable stream (Bimap k a) where
encode p m = encode p (toMap m^.keyed & toList)
instance (Ord k,Ord a,Format stream k,Format stream a) => Format stream (Bimap k a) where
datum = datum <&> fromAList
instance Serializable stream a => Serializable stream (Set a) where
encode p = encode p . toList
instance (Ord a,Format stream a) => Format stream (Set a) where
datum = datum <&> fromKList
instance (Ord a,Ord b,Serializable stream a,Serializable stream b,Serializable stream e) => Serializable stream (Relation e a b) where
encode p = encode p . (^.i'ranges)
instance (Ord a,Ord b,Format stream a,Format stream b,Format stream e) => Format stream (Relation e a b) where
datum = yb i'ranges <$> datum
instance (Ord a,Serializable stream a,Serializable stream e) => Serializable stream (Equiv e a) where
encode p (Equiv e) = encode p (toList (e^.i'domains) <&> \d -> let l = d^.ascList in (snd (head l),map fst l))
instance (Ord a,Format stream a,Format stream e) => Format stream (Equiv e a) where
datum = datum <&> Equiv . \l -> fromAList [(a,yb ascList (map (,e) as)) | (e,as@(a:_)) <- l]^..i'domains
instance Serializable stream a => Serializable stream (Range a) where
encode = coerceEncode Range
instance Format stream a => Format stream (Range a) where
datum = coerceDatum Range
instance (Serializable stream a,Serializable stream b) => Serializable stream (a:*:b) where
encode p (a,b) = encode p a+encode p b
instance (Format stream a,Format stream b) => Format stream (a:*:b) where
datum = (,)<$>datum<*>datum
instance (Serializable stream a,Serializable stream b,Serializable stream c) => Serializable stream (a,b,c) where
encode p (a,b,c) = encode p a+encode p b+encode p c
instance (Format stream a,Format stream b,Format stream c) => Format stream (a,b,c) where
datum = (,,)<$>datum<*>datum<*>datum
instance (Serializable stream a,Serializable stream b,Serializable stream c,Serializable stream d) => Serializable stream (a,b,c,d) where
encode p (a,b,c,d) = encode p a+encode p b+encode p c+encode p d
instance (Format stream a,Format stream b,Format stream c,Format stream d) => Format stream (a,b,c,d) where
datum = (,,,)<$>datum<*>datum<*>datum<*>datum
instance (Serializable stream a,Serializable stream b,Serializable stream c,Serializable stream d,Serializable stream e) => Serializable stream (a,b,c,d,e) where
encode p (a,b,c,d,e) = encode p a+encode p b+encode p c+encode p d+encode p e
instance (Format stream a,Format stream b,Format stream c,Format stream d,Format stream e) => Format stream (a,b,c,d,e) where
datum = (,,,,)<$>datum<*>datum<*>datum<*>datum<*>datum
instance (Serializable stream a,Serializable stream b,Serializable stream c,Serializable stream d,Serializable stream e,Serializable stream f) => Serializable stream (a,b,c,d,e,f) where
encode p (a,b,c,d,e,f) = encode p a+encode p b+encode p c+encode p d+encode p e+encode p f
instance (Format stream a,Format stream b,Format stream c,Format stream d,Format stream e,Format stream f) => Format stream (Tuple6 a b c d e f) where
datum = (,,,,,)<$>datum<*>datum<*>datum<*>datum<*>datum<*>datum
instance (Serializable stream a,Serializable stream b,Serializable stream c,Serializable stream d,Serializable stream e,Serializable stream f,Serializable stream g) => Serializable stream (a,b,c,d,e,f,g) where
encode p (a,b,c,d,e,f,g) = encode p a+encode p b+encode p c+encode p d+encode p e+encode p f+encode p g
instance (Format stream a,Format stream b,Format stream c,Format stream d,Format stream e,Format stream f,Format stream g) => Format stream (Tuple7 a b c d e f g) where
datum = (,,,,,,)<$>datum<*>datum<*>datum<*>datum<*>datum<*>datum<*>datum
instance (Serializable stream a,Serializable stream b,Serializable stream c,Serializable stream d,Serializable stream e,Serializable stream f,Serializable stream g,Serializable stream h) => Serializable stream (a,b,c,d,e,f,g,h) where
encode p (a,b,c,d,e,f,g,h) = encode p a+encode p b+encode p c+encode p d+encode p e+encode p f+encode p g+encode p h
instance (Format stream a,Format stream b,Format stream c,Format stream d,Format stream e,Format stream f,Format stream g,Format stream h) => Format stream (Tuple8 a b c d e f g h) where
datum = (,,,,,,,)<$>datum<*>datum<*>datum<*>datum<*>datum<*>datum<*>datum<*>datum
instance (Serializable stream a,Serializable stream b,Serializable stream c,Serializable stream d,Serializable stream e,Serializable stream f,Serializable stream g,Serializable stream h,Serializable stream i) => Serializable stream (a,b,c,d,e,f,g,h,i) where
encode p (a,b,c,d,e,f,g,h,i) = encode p a+encode p b+encode p c+encode p d+encode p e+encode p f+encode p g+encode p h+encode p i
instance (Format stream a,Format stream b,Format stream c,Format stream d,Format stream e,Format stream f,Format stream g,Format stream h,Format stream i) => Format stream (Tuple9 a b c d e f g h i) where
datum = (,,,,,,,,)<$>datum<*>datum<*>datum<*>datum<*>datum<*>datum<*>datum<*>datum<*>datum
instance (Serializable stream a,Serializable stream b) => Serializable stream (a:+:b) where
encode p (Left a) = encodeAlt p 0 a
encode p (Right a) = encodeAlt p 1 a
instance (Serializable stream a,Serializable stream b,Serializable stream c) => Serializable stream (Union3 a b c) where
encode p (U3_1 a) = encodeAlt p 0 a
encode p (U3_2 b) = encodeAlt p 1 b
encode p (U3_3 c) = encodeAlt p 2 c
instance (Serializable stream a,Serializable stream b,Serializable stream c,Serializable stream d) => Serializable stream (Union4 a b c d) where
encode p (U4_1 x) = encodeAlt p 0 x
encode p (U4_2 x) = encodeAlt p 1 x
encode p (U4_3 x) = encodeAlt p 2 x
encode p (U4_4 x) = encodeAlt p 3 x
instance (Serializable stream a,Serializable stream b,Serializable stream c,Serializable stream d,Serializable stream e) => Serializable stream (Union5 a b c d e) where
encode p (U5_1 x) = encodeAlt p 0 x
encode p (U5_2 x) = encodeAlt p 1 x
encode p (U5_3 x) = encodeAlt p 2 x
encode p (U5_4 x) = encodeAlt p 3 x
encode p (U5_5 x) = encodeAlt p 4 x
instance (Serializable stream a,Serializable stream b,Serializable stream c,Serializable stream d,Serializable stream e,Serializable stream f) => Serializable stream (Union6 a b c d e f) where
encode p (U6_1 x) = encodeAlt p 0 x
encode p (U6_2 x) = encodeAlt p 1 x
encode p (U6_3 x) = encodeAlt p 2 x
encode p (U6_4 x) = encodeAlt p 3 x
encode p (U6_5 x) = encodeAlt p 4 x
encode p (U6_6 x) = encodeAlt p 5 x
instance (Serializable stream a,Serializable stream b,Serializable stream c,Serializable stream d,Serializable stream e,Serializable stream f,Serializable stream g) => Serializable stream (Union7 a b c d e f g) where
encode p (U7_1 x) = encodeAlt p 0 x
encode p (U7_2 x) = encodeAlt p 1 x
encode p (U7_3 x) = encodeAlt p 2 x
encode p (U7_4 x) = encodeAlt p 3 x
encode p (U7_5 x) = encodeAlt p 4 x
encode p (U7_6 x) = encodeAlt p 5 x
encode p (U7_7 x) = encodeAlt p 6 x
instance (Serializable stream a,Serializable stream b,Serializable stream c,Serializable stream d,Serializable stream e,Serializable stream f,Serializable stream g,Serializable stream h) => Serializable stream (Union8 a b c d e f g h) where
encode p (U8_1 x) = encodeAlt p 0 x
encode p (U8_2 x) = encodeAlt p 1 x
encode p (U8_3 x) = encodeAlt p 2 x
encode p (U8_4 x) = encodeAlt p 3 x
encode p (U8_5 x) = encodeAlt p 4 x
encode p (U8_6 x) = encodeAlt p 5 x
encode p (U8_7 x) = encodeAlt p 6 x
encode p (U8_8 x) = encodeAlt p 7 x
instance (Serializable stream a,Serializable stream b,Serializable stream c,Serializable stream d,Serializable stream e,Serializable stream f,Serializable stream g,Serializable stream h,Serializable stream i) => Serializable stream (Union9 a b c d e f g h i) where
encode p (U9_1 x) = encodeAlt p 0 x
encode p (U9_2 x) = encodeAlt p 1 x
encode p (U9_3 x) = encodeAlt p 2 x
encode p (U9_4 x) = encodeAlt p 3 x
encode p (U9_5 x) = encodeAlt p 4 x
encode p (U9_6 x) = encodeAlt p 5 x
encode p (U9_7 x) = encodeAlt p 6 x
encode p (U9_8 x) = encodeAlt p 7 x
encode p (U9_9 x) = encodeAlt p 8 x
instance (Format stream a,Format stream b) => Format stream (a:+:b) where
datum = datumOf [FormatAlt Left,FormatAlt Right]
instance (Format stream a,Format stream b,Format stream c) => Format stream (Union3 a b c) where
datum = datumOf [FormatAlt U3_1,FormatAlt U3_2,FormatAlt U3_3]
instance (Format stream a,Format stream b,Format stream c,Format stream d) => Format stream (Union4 a b c d) where
datum = datumOf [FormatAlt U4_1,FormatAlt U4_2,FormatAlt U4_3,FormatAlt U4_4]
instance (Format stream a,Format stream b,Format stream c,Format stream d,Format stream e) => Format stream (Union5 a b c d e) where
datum = datumOf [FormatAlt U5_1,FormatAlt U5_2,FormatAlt U5_3,FormatAlt U5_4,FormatAlt U5_5]
instance (Format stream a,Format stream b,Format stream c,Format stream d,Format stream e,Format stream f) => Format stream (Union6 a b c d e f) where
datum = datumOf [FormatAlt U6_1,FormatAlt U6_2,FormatAlt U6_3,FormatAlt U6_4,FormatAlt U6_5,FormatAlt U6_6]
instance (Format stream a,Format stream b,Format stream c,Format stream d,Format stream e,Format stream f,Format stream g) => Format stream (Union7 a b c d e f g) where
datum = datumOf [FormatAlt U7_1,FormatAlt U7_2,FormatAlt U7_3,FormatAlt U7_4,FormatAlt U7_5,FormatAlt U7_6,FormatAlt U7_7]
instance (Format stream a,Format stream b,Format stream c,Format stream d,Format stream e,Format stream f,Format stream g,Format stream h) => Format stream (Union8 a b c d e f g h) where
datum = datumOf [FormatAlt U8_1,FormatAlt U8_2,FormatAlt U8_3,FormatAlt U8_4,FormatAlt U8_5,FormatAlt U8_6,FormatAlt U8_7,FormatAlt U8_8]
instance (Format stream a,Format stream b,Format stream c,Format stream d,Format stream e,Format stream f,Format stream g,Format stream h,Format stream i) => Format stream (Union9 a b c d e f g h i) where
datum = datumOf [FormatAlt U9_1,FormatAlt U9_2,FormatAlt U9_3,FormatAlt U9_4,FormatAlt U9_5,FormatAlt U9_6,FormatAlt U9_7,FormatAlt U9_8,FormatAlt U9_9]