packages feed

colonnade 0.1 → 0.3

raw patch · 5 files changed

+214/−14 lines, 5 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Colonnade.Internal.Ap: [Ap] :: f a -> Ap f (a -> b) -> Ap f b
- Colonnade.Internal.Ap: [Pure] :: a -> Ap f a
- Colonnade.Types: [DecodingAp] :: !(f content) -> !(content -> Either String a) -> !(Decoding f content (a -> b)) -> Decoding f content b
- Colonnade.Types: [DecodingPure] :: !a -> Decoding f content a
+ Colonnade.Decoding: columnNumToLetters :: Int -> String
+ Colonnade.Decoding: headedToIndexed :: Eq content => Vector content -> Decoding Headed content a -> Either (HeadingErrors content) (Decoding (Indexed Headed) content a)
+ Colonnade.Decoding: headlessToIndexed :: Decoding Headless c a -> Decoding (Indexed Headless) c a
+ Colonnade.Decoding: indexed :: Int -> (content -> Either String a) -> Decoding (Indexed Headless) content a
+ Colonnade.Decoding: length :: Decoding f c a -> Int
+ Colonnade.Decoding: maxIndex :: Decoding (Indexed f) c a -> Int
+ Colonnade.Decoding: prettyCellErrors :: (c -> String) -> DecodingCellErrors f c -> [String]
+ Colonnade.Decoding: prettyError :: (c -> String) -> DecodingRowError f c -> String
+ Colonnade.Decoding: prettyHeadingErrors :: (c -> String) -> HeadingErrors c -> [String]
+ Colonnade.Decoding: prettyRowError :: (content -> String) -> RowError f content -> (String, [String])
+ Colonnade.Decoding: uncheckedRun :: Decoding (Indexed f) content a -> Vector content -> Either (DecodingCellErrors f content) a
+ Colonnade.Decoding: uncheckedRunWithRow :: Int -> Decoding (Indexed f) content a -> Vector content -> Either (DecodingRowError f content) a
+ Colonnade.Decoding.ByteString.Char8: bool :: ByteString -> Either String Bool
+ Colonnade.Decoding.ByteString.Char8: char :: ByteString -> Either String Char
+ Colonnade.Decoding.ByteString.Char8: int :: ByteString -> Either String Int
+ Colonnade.Decoding.Text: char :: Text -> Either String Char
+ Colonnade.Decoding.Text: fromReader :: Reader a -> Text -> Either String a
+ Colonnade.Decoding.Text: int :: Text -> Either String Int
+ Colonnade.Decoding.Text: map :: (a -> b) -> (Text -> Either String a) -> Text -> Either String b
+ Colonnade.Decoding.Text: optional :: (Text -> Either String a) -> Text -> Either String (Maybe a)
+ Colonnade.Decoding.Text: text :: Text -> Either String Text
+ Colonnade.Decoding.Text: trueFalse :: Text -> Text -> Text -> Either String Bool
+ Colonnade.Encoding: columns :: (b -> a -> c) -> (b -> f c) -> Vector b -> Encoding f c a
+ Colonnade.Encoding: fromMaybe :: c -> Encoding f c a -> Encoding f c (Maybe a)
+ Colonnade.Encoding: runHeader :: (c1 -> c2) -> Encoding Headed c1 a -> Vector c2
+ Colonnade.Encoding: runHeaderMonadic :: (Monad m, Monoid b) => Encoding Headed content a -> (content -> m b) -> m b
+ Colonnade.Encoding: runRow :: (c1 -> c2) -> Encoding f c1 a -> a -> Vector c2
+ Colonnade.Encoding: runRowMonadic :: (Monad m, Monoid b) => Encoding f content a -> (content -> m b) -> a -> m b
+ Colonnade.Encoding.ByteString.Char8: bool :: Bool -> ByteString
+ Colonnade.Encoding.ByteString.Char8: byteString :: ByteString -> ByteString
+ Colonnade.Encoding.ByteString.Char8: char :: Char -> ByteString
+ Colonnade.Encoding.ByteString.Char8: int :: Int -> ByteString
+ Colonnade.Encoding.Text: bool :: Bool -> Text
+ Colonnade.Encoding.Text: char :: Char -> Text
+ Colonnade.Encoding.Text: int :: Int -> Text
+ Colonnade.Encoding.Text: text :: Text -> Text
+ Colonnade.Internal: EitherWrap :: Either a b -> EitherWrap a b
+ Colonnade.Internal: [getEitherWrap] :: EitherWrap a b -> Either a b
+ Colonnade.Internal: instance GHC.Base.Functor (Colonnade.Internal.EitherWrap a)
+ Colonnade.Internal: instance GHC.Base.Monoid a => GHC.Base.Applicative (Colonnade.Internal.EitherWrap a)
+ Colonnade.Internal: mapLeft :: (a -> b) -> Either a c -> Either b c
+ Colonnade.Internal: newtype EitherWrap a b
+ Colonnade.Internal.Ap: Ap :: f a -> Ap f (a -> b) -> Ap f b
+ Colonnade.Internal.Ap: Pure :: a -> Ap f a
+ Colonnade.Types: DecodingAp :: !(f content) -> !(content -> Either String a) -> !(Decoding f content (a -> b)) -> Decoding f content b
+ Colonnade.Types: DecodingCellError :: !content -> !(Indexed f content) -> !String -> DecodingCellError f content
+ Colonnade.Types: DecodingCellErrors :: Vector (DecodingCellError f content) -> DecodingCellErrors f content
+ Colonnade.Types: DecodingPure :: !a -> Decoding f content a
+ Colonnade.Types: DecodingRowError :: !Int -> !(RowError f content) -> DecodingRowError f content
+ Colonnade.Types: HeadingErrors :: Vector content -> Vector (content, Int) -> HeadingErrors content
+ Colonnade.Types: Indexed :: !Int -> !(f a) -> Indexed f a
+ Colonnade.Types: OneEncoding :: !(f content) -> !(a -> content) -> OneEncoding f content a
+ Colonnade.Types: RowErrorDecode :: !(DecodingCellErrors f content) -> RowError f content
+ Colonnade.Types: RowErrorHeading :: !(HeadingErrors content) -> RowError f content
+ Colonnade.Types: RowErrorMalformed :: !String -> RowError f content
+ Colonnade.Types: RowErrorMinSize :: !Int -> !Int -> RowError f content
+ Colonnade.Types: RowErrorParse :: !String -> RowError f content
+ Colonnade.Types: RowErrorSize :: !Int -> !Int -> RowError f content
+ Colonnade.Types: [decodingCellErrorContent] :: DecodingCellError f content -> !content
+ Colonnade.Types: [decodingCellErrorHeader] :: DecodingCellError f content -> !(Indexed f content)
+ Colonnade.Types: [decodingCellErrorMessage] :: DecodingCellError f content -> !String
+ Colonnade.Types: [decodingRowErrorError] :: DecodingRowError f content -> !(RowError f content)
+ Colonnade.Types: [decodingRowErrorRow] :: DecodingRowError f content -> !Int
+ Colonnade.Types: [getDecodingCellErrors] :: DecodingCellErrors f content -> Vector (DecodingCellError f content)
+ Colonnade.Types: [headingErrorsDuplicate] :: HeadingErrors content -> Vector (content, Int)
+ Colonnade.Types: [headingErrorsMissing] :: HeadingErrors content -> Vector content
+ Colonnade.Types: [indexedHeading] :: Indexed f a -> !(f a)
+ Colonnade.Types: [indexedIndex] :: Indexed f a -> !Int
+ Colonnade.Types: [oneEncodingEncode] :: OneEncoding f content a -> !(a -> content)
+ Colonnade.Types: [oneEncodingHead] :: OneEncoding f content a -> !(f content)
+ Colonnade.Types: data DecodingCellError f content
+ Colonnade.Types: data DecodingRowError f content
+ Colonnade.Types: data HeadingErrors content
+ Colonnade.Types: data Indexed f a
+ Colonnade.Types: data OneEncoding f content a
+ Colonnade.Types: data RowError f content
+ Colonnade.Types: instance (GHC.Classes.Eq content, GHC.Classes.Eq (f content)) => GHC.Classes.Eq (Colonnade.Types.DecodingCellError f content)
+ Colonnade.Types: instance (GHC.Classes.Eq content, GHC.Classes.Eq (f content)) => GHC.Classes.Eq (Colonnade.Types.DecodingCellErrors f content)
+ Colonnade.Types: instance (GHC.Classes.Eq content, GHC.Classes.Eq (f content)) => GHC.Classes.Eq (Colonnade.Types.DecodingRowError f content)
+ Colonnade.Types: instance (GHC.Classes.Eq content, GHC.Classes.Eq (f content)) => GHC.Classes.Eq (Colonnade.Types.RowError f content)
+ Colonnade.Types: instance (GHC.Read.Read content, GHC.Read.Read (f content)) => GHC.Read.Read (Colonnade.Types.DecodingCellError f content)
+ Colonnade.Types: instance (GHC.Read.Read content, GHC.Read.Read (f content)) => GHC.Read.Read (Colonnade.Types.DecodingCellErrors f content)
+ Colonnade.Types: instance (GHC.Read.Read content, GHC.Read.Read (f content)) => GHC.Read.Read (Colonnade.Types.DecodingRowError f content)
+ Colonnade.Types: instance (GHC.Read.Read content, GHC.Read.Read (f content)) => GHC.Read.Read (Colonnade.Types.RowError f content)
+ Colonnade.Types: instance (GHC.Show.Show content, Data.Typeable.Internal.Typeable content) => GHC.Exception.Exception (Colonnade.Types.HeadingErrors content)
+ Colonnade.Types: instance (GHC.Show.Show content, GHC.Show.Show (f content)) => GHC.Show.Show (Colonnade.Types.DecodingCellError f content)
+ Colonnade.Types: instance (GHC.Show.Show content, GHC.Show.Show (f content)) => GHC.Show.Show (Colonnade.Types.DecodingCellErrors f content)
+ Colonnade.Types: instance (GHC.Show.Show content, GHC.Show.Show (f content)) => GHC.Show.Show (Colonnade.Types.DecodingRowError f content)
+ Colonnade.Types: instance (GHC.Show.Show content, GHC.Show.Show (f content)) => GHC.Show.Show (Colonnade.Types.RowError f content)
+ Colonnade.Types: instance Data.Foldable.Foldable Colonnade.Types.Headed
+ Colonnade.Types: instance Data.Foldable.Foldable Colonnade.Types.Headless
+ Colonnade.Types: instance Data.Functor.Contravariant.Contravariant (Colonnade.Types.OneEncoding f content)
+ Colonnade.Types: instance GHC.Base.Functor f => GHC.Base.Functor (Colonnade.Types.Indexed f)
+ Colonnade.Types: instance GHC.Base.Monoid (Colonnade.Types.DecodingCellErrors f content)
+ Colonnade.Types: instance GHC.Base.Monoid (Colonnade.Types.HeadingErrors content)
+ Colonnade.Types: instance GHC.Classes.Eq (f a) => GHC.Classes.Eq (Colonnade.Types.Indexed f a)
+ Colonnade.Types: instance GHC.Classes.Eq content => GHC.Classes.Eq (Colonnade.Types.HeadingErrors content)
+ Colonnade.Types: instance GHC.Classes.Ord (f a) => GHC.Classes.Ord (Colonnade.Types.Indexed f a)
+ Colonnade.Types: instance GHC.Read.Read (f a) => GHC.Read.Read (Colonnade.Types.Indexed f a)
+ Colonnade.Types: instance GHC.Read.Read content => GHC.Read.Read (Colonnade.Types.HeadingErrors content)
+ Colonnade.Types: instance GHC.Show.Show (f a) => GHC.Show.Show (Colonnade.Types.Indexed f a)
+ Colonnade.Types: instance GHC.Show.Show content => GHC.Show.Show (Colonnade.Types.HeadingErrors content)
+ Colonnade.Types: newtype DecodingCellErrors f content
- Colonnade.Decoding: contramapContent :: forall c1 c2 f a. Contravariant f => (c2 -> c1) -> Decoding f c1 a -> Decoding f c2 a
+ Colonnade.Decoding: contramapContent :: Contravariant f => (c2 -> c1) -> Decoding f c1 a -> Decoding f c2 a
- Colonnade.Types: Encoding :: Vector (f content, a -> content) -> Encoding f content a
+ Colonnade.Types: Encoding :: Vector (OneEncoding f content a) -> Encoding f content a
- Colonnade.Types: [getEncoding] :: Encoding f content a -> Vector (f content, a -> content)
+ Colonnade.Types: [getEncoding] :: Encoding f content a -> Vector (OneEncoding f content a)

Files

colonnade.cabal view
@@ -1,5 +1,5 @@ name:                colonnade-version:             0.1+version:             0.3 synopsis:            Generic types and functions for columnar encoding and decoding description:         Please see README.md homepage:            https://github.com/andrewthad/colonnade#readme@@ -18,6 +18,7 @@     Colonnade.Types     Colonnade.Encoding     Colonnade.Decoding+    Colonnade.Internal     Colonnade.Internal.Ap   build-depends:       base >= 4.7 && < 5
src/Colonnade/Decoding.hs view
@@ -1,9 +1,13 @@ {-# LANGUAGE RankNTypes          #-} {-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE BangPatterns        #-} module Colonnade.Decoding where +import Colonnade.Internal (EitherWrap(..)) import Colonnade.Types import Data.Functor.Contravariant+import Data.Vector (Vector)+import qualified Data.Vector as Vector  -- | Converts the content type of a 'Decoding'. The @'Contravariant' f@ -- constraint means that @f@ can be 'Headless' but not 'Headed'.@@ -21,4 +25,90 @@ headed :: content -> (content -> Either String a) -> Decoding Headed content a headed h f = DecodingAp (Headed h) f (DecodingPure id) +indexed :: Int -> (content -> Either String a) -> Decoding (Indexed Headless) content a+indexed ix f = DecodingAp (Indexed ix Headless) f (DecodingPure id)++maxIndex :: forall f c a. Decoding (Indexed f) c a -> Int+maxIndex = go 0 where+  go :: forall b. Int -> Decoding (Indexed f) c b -> Int+  go !ix (DecodingPure _) = ix+  go !ix1 (DecodingAp (Indexed ix2 _) decode apNext) =+    go (max ix1 ix2) apNext++-- | This function uses 'unsafeIndex' to access+--   elements of the 'Vector'.+uncheckedRunWithRow ::+     Int+  -> Decoding (Indexed f) content a+  -> Vector content+  -> Either (DecodingRowError f content) a+uncheckedRunWithRow i d v = mapLeft (DecodingRowError i . RowErrorDecode) (uncheckedRun d v)++-- | This function does not check to make sure that the indicies in+--   the 'Decoding' are in the 'Vector'.+uncheckedRun :: forall content a f.+                Decoding (Indexed f) content a+             -> Vector content+             -> Either (DecodingCellErrors f content) a+uncheckedRun dc v = getEitherWrap (go dc)+  where+  go :: forall b.+        Decoding (Indexed f) content b+     -> EitherWrap (DecodingCellErrors f content) b+  go (DecodingPure b) = EitherWrap (Right b)+  go (DecodingAp ixed@(Indexed ix h) decode apNext) =+    let rnext = go apNext+        content = Vector.unsafeIndex v ix+        rcurrent = mapLeft (DecodingCellErrors . Vector.singleton . DecodingCellError content ixed) (decode content)+    in rnext <*> (EitherWrap rcurrent)++headlessToIndexed :: forall c a.+  Decoding Headless c a -> Decoding (Indexed Headless) c a+headlessToIndexed = go 0 where+  go :: forall b. Int -> Decoding Headless c b -> Decoding (Indexed Headless) c b+  go !ix (DecodingPure a) = DecodingPure a+  go !ix (DecodingAp Headless decode apNext) =+    DecodingAp (Indexed ix Headless) decode (go (ix + 1) apNext)++length :: forall f c a. Decoding f c a -> Int+length = go 0 where+  go :: forall b. Int -> Decoding f c b -> Int+  go !a (DecodingPure _) = a+  go !a (DecodingAp _ _ apNext) = go (a + 1) apNext++-- | Maps over a 'Decoding' that expects headers, converting these+--   expected headers into the indices of the columns that they+--   correspond to.+headedToIndexed :: forall content a. Eq content+                => Vector content -- ^ Headers in the source document+                -> Decoding Headed content a -- ^ Decoding that contains expected headers+                -> Either (HeadingErrors content) (Decoding (Indexed Headed) content a)+headedToIndexed v = getEitherWrap . go+  where+  go :: forall b. Eq content+     => Decoding Headed content b+     -> EitherWrap (HeadingErrors content) (Decoding (Indexed Headed) content b)+  go (DecodingPure b) = EitherWrap (Right (DecodingPure b))+  go (DecodingAp hd@(Headed h) decode apNext) =+    let rnext = go apNext+        ixs = Vector.elemIndices h v+        ixsLen = Vector.length ixs+        rcurrent+          | ixsLen == 1 = Right (Vector.unsafeIndex ixs 0)+          | ixsLen == 0 = Left (HeadingErrors (Vector.singleton h) Vector.empty)+          | otherwise   = Left (HeadingErrors Vector.empty (Vector.singleton (h,ixsLen)))+    in (\ix ap -> DecodingAp (Indexed ix hd) decode ap)+       <$> EitherWrap rcurrent+       <*> rnext++eitherMonoidAp :: Monoid a => Either a (b -> c) -> Either a b -> Either a c+eitherMonoidAp = go where+  go (Left a1) (Left a2) = Left (mappend a1 a2)+  go (Left a1) (Right _) = Left a1+  go (Right _) (Left a2) = Left a2+  go (Right f) (Right b) = Right (f b)++mapLeft :: (a -> b) -> Either a c -> Either b c+mapLeft _ (Right a) = Right a+mapLeft f (Left a) = Left (f a) 
src/Colonnade/Encoding.hs view
@@ -1,15 +1,47 @@ module Colonnade.Encoding where  import Colonnade.Types+import Data.Vector (Vector) import qualified Data.Vector as Vector  mapContent :: Functor f => (c1 -> c2) -> Encoding f c1 a -> Encoding f c2 a mapContent f (Encoding v) = Encoding-  $ Vector.map (\(h,c) -> (fmap f h,f . c)) v+  $ Vector.map (\(OneEncoding h c) -> (OneEncoding (fmap f h) (f . c))) v  headless :: (a -> content) -> Encoding Headless content a-headless f = Encoding (Vector.singleton (Headless,f))+headless f = Encoding (Vector.singleton (OneEncoding Headless f))  headed :: content -> (a -> content) -> Encoding Headed content a-headed h f = Encoding (Vector.singleton (Headed h,f))+headed h f = Encoding (Vector.singleton (OneEncoding (Headed h) f))++-- runRow' :: Encoding f content a -> a -> Vector content+-- runRow' = runRow id++-- | Consider providing a variant the produces a list+-- instead. It may allow more things to get inlined+-- in to a loop.+runRow :: (c1 -> c2) -> Encoding f c1 a -> a -> Vector c2+runRow g (Encoding v) a = flip Vector.map v $+  \(OneEncoding _ encode) -> g (encode a)++runRowMonadic :: (Monad m, Monoid b)+              => Encoding f content a+              -> (content -> m b)+              -> a+              -> m b+runRowMonadic (Encoding v) g a = fmap (mconcat . Vector.toList) $ Vector.forM v $ \e ->+  g (oneEncodingEncode e a)++runHeader :: (c1 -> c2) -> Encoding Headed c1 a -> Vector c2+runHeader g (Encoding v) =+  Vector.map (g . getHeaded . oneEncodingHead) v++runHeaderMonadic :: (Monad m, Monoid b)+                 => Encoding Headed content a+                 -> (content -> m b)+                 -> m b+runHeaderMonadic (Encoding v) g =+  fmap (mconcat . Vector.toList) $ Vector.mapM (g . getHeaded . oneEncodingHead) v++ 
+ src/Colonnade/Internal.hs view
@@ -0,0 +1,14 @@+{-# LANGUAGE DeriveFunctor #-}+module Colonnade.Internal where++newtype EitherWrap a b = EitherWrap+  { getEitherWrap :: Either a b+  } deriving (Functor)++instance Monoid a => Applicative (EitherWrap a) where+  pure = EitherWrap . Right+  EitherWrap (Left a1) <*> EitherWrap (Left a2) = EitherWrap (Left (mappend a1 a2))+  EitherWrap (Left a1) <*> EitherWrap (Right _) = EitherWrap (Left a1)+  EitherWrap (Right _) <*> EitherWrap (Left a2) = EitherWrap (Left a2)+  EitherWrap (Right f) <*> EitherWrap (Right b) = EitherWrap (Right (f b))+
src/Colonnade/Types.hs view
@@ -4,13 +4,22 @@ module Colonnade.Types   ( Encoding(..)   , Decoding(..)+  , OneEncoding(..)   , Headed(..)   , Headless(..)+  , Indexed(..)+  , HeadingErrors(..)+  , DecodingCellError(..)+  , DecodingRowError(..)+  , DecodingCellErrors(..)+  , RowError(..)   ) where  import Data.Vector (Vector) import Data.Functor.Contravariant (Contravariant(..)) import Data.Functor.Contravariant.Divisible (Divisible(..))+import Control.Exception (Exception)+import Data.Typeable (Typeable) import qualified Data.Vector as Vector  -- | Isomorphic to 'Identity'@@ -21,6 +30,51 @@ data Headless a = Headless   deriving (Eq,Ord,Functor,Show,Read) +data Indexed f a = Indexed+  { indexedIndex :: !Int+  , indexedHeading :: !(f a)+  } deriving (Eq,Ord,Functor,Show,Read)++data HeadingErrors content = HeadingErrors+  { headingErrorsMissing   :: Vector content       -- ^ headers that were missing+  , headingErrorsDuplicate :: Vector (content,Int) -- ^ headers that occurred more than once+  } deriving (Show,Read)++instance (Show content, Typeable content) => Exception (HeadingErrors content)++instance Monoid (HeadingErrors content) where+  mempty = HeadingErrors Vector.empty Vector.empty+  mappend (HeadingErrors a1 b1) (HeadingErrors a2 b2) = HeadingErrors+    (a1 Vector.++ a2) (b1 Vector.++ b2)++data DecodingCellError f content = DecodingCellError+  { decodingCellErrorContent :: !content+  , decodingCellErrorHeader  :: !(Indexed f content)+  , decodingCellErrorMessage :: !String+  } deriving (Show,Read)++-- instance (Show (f content), Typeable content) => Exception (DecodingError f content)++newtype DecodingCellErrors f content = DecodingCellErrors+  { getDecodingCellErrors :: Vector (DecodingCellError f content)+  } deriving (Monoid,Show,Read)++-- newtype ParseRowError = ParseRowError String++data DecodingRowError f content = DecodingRowError+  { decodingRowErrorRow   :: !Int+  , decodingRowErrorError :: !(RowError f content)+  }++data RowError f content+  = RowErrorParse !String -- ^ Error occurred parsing the document into cells+  | RowErrorDecode !(DecodingCellErrors f content) -- ^ Error decoding the content+  | RowErrorSize !Int !Int -- ^ Wrong number of cells in the row+  | RowErrorHeading !(HeadingErrors content)+  | RowErrorMinSize !Int !Int++-- instance (Show (f content), Typeable content) => Exception (DecodingErrors f content)+ instance Contravariant Headless where   contramap _ Headless = Headless @@ -28,11 +82,11 @@ --   Check out @Control.Applicative.Free@ in the @free@ library to --   learn more about this. data Decoding f content a where-  DecodingPure :: !a+  DecodingPure :: !a -- ^ function                -> Decoding f content a-  DecodingAp :: !(f content)-             -> !(content -> Either String a)-             -> !(Decoding f content (a -> b))+  DecodingAp :: !(f content) -- ^ header+             -> !(content -> Either String a) -- ^ decoding function+             -> !(Decoding f content (a -> b)) -- ^ next decoding              -> Decoding f content b  instance Functor (Decoding f content) where@@ -44,19 +98,28 @@   DecodingPure f <*> y = fmap f y   DecodingAp h c y <*> z = DecodingAp h c (flip <$> y <*> z) +data OneEncoding f content a = OneEncoding+  { oneEncodingHead   :: !(f content)+  , oneEncodingEncode :: !(a -> content)+  }++instance Contravariant (OneEncoding f content) where+  contramap f (OneEncoding h e) = OneEncoding h (e . f)+ newtype Encoding f content a = Encoding-  { getEncoding :: Vector (f content,a -> content) }-  deriving (Monoid)+  { getEncoding :: Vector (OneEncoding f content a)+  } deriving (Monoid)  instance Contravariant (Encoding f content) where   contramap f (Encoding v) = Encoding-    (Vector.map (\(h,c) -> (h, c . f)) v)+    (Vector.map (contramap f) v)  instance Divisible (Encoding f content) where   conquer = Encoding Vector.empty   divide f (Encoding a) (Encoding b) =     Encoding $ (Vector.++)-      (Vector.map (\(h,c) -> (h,c . fst . f)) a)-      (Vector.map (\(h,c) -> (h,c . snd . f)) b)-+      (Vector.map (contramap (fst . f)) a)+      (Vector.map (contramap (snd . f)) b)+      -- (Vector.map (\(OneEncoding h c) -> (h,c . fst . f)) a)+      -- (Vector.map (\(OneEncoding h c) -> (h,c . snd . f)) b)