-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | A type class for Matchable Functors. -- -- This package provides a type class Matchable, which -- represents zipMatch operation which can zip two values if -- these two have exactly same shape. @package matchable @version 0.1.2 module Data.Bimatchable -- | Containers that allows exact structural matching of two containers. -- -- Bimatchable is Bifunctor-version of -- Matchable. It can compare and zip containers with two -- parameters. class (Eq2 t, Bifunctor t) => Bimatchable t -- | bizipMatch is to zipMatch what bimap is to -- fmap. -- -- Decides if two structures match exactly. If they match, return zipped -- version of them. -- --

Law

-- -- Forall x :: t a b, y :: t a' b', z :: t (a,a') -- (b,b'), -- --
--   bizipMatch x y = Just z
--   
-- -- holds if and only if both of -- --
--   x = bimap fst fst z
--   y = bimap snd snd z
--   
-- -- holds. Otherwise, bizipMatch x y = Nothing. -- --

Example

-- --
--   >>> bizipMatch (Left 1) (Left 'a')
--   Just (Left (1,'a'))
--   
--   >>> bizipMatch (Right 1) (Right False)
--   Just (Right (1,False))
--   
--   >>> bizipMatch (Left 1) (Right False)
--   Nothing
--   
bizipMatch :: Bimatchable t => t a b -> t a' b' -> Maybe (t (a, a') (b, b')) -- | bizipMatchWith is to zipMatchWith what bimap is -- to fmap. -- -- Match two structures. If they match, zip them with given functions -- (a -> a' -> Maybe a'') and (b -> b -> Maybe -- b''). Passed functions can make whole match failby returning -- Nothing. -- --

Law

-- -- For any -- --
--   x :: t a b
--   y :: t a' b'
--   f :: a -> a' -> Maybe a''
--   g :: b -> b' -> Maybe b''
--   
-- -- bizipMatchWith must satisfy the following. -- -- bizipMatchWith :: Bimatchable t => (a -> a' -> Maybe a'') -> (b -> b' -> Maybe b'') -> t a b -> t a' b' -> Maybe (t a'' b'') bimapRecovered :: Bimatchable t => (a -> a') -> (b -> b') -> t a b -> t a' b' eq2Default :: (Bimatchable t, Eq a, Eq b) => t a b -> t a b -> Bool liftEq2Default :: Bimatchable t => (a -> a' -> Bool) -> (b -> b' -> Bool) -> t a b -> t a' b' -> Bool instance Data.Bimatchable.Bimatchable Data.Either.Either instance Data.Bimatchable.Bimatchable (,) instance Data.Bimatchable.Bimatchable Data.Functor.Const.Const instance Data.Bimatchable.Bimatchable Data.Tagged.Tagged module Data.Matchable -- | Containers that allows exact structural matching of two containers. class (Eq1 t, Functor t) => Matchable t -- | Decides if two structures match exactly. If they match, return zipped -- version of them. -- --
--   zipMatch ta tb = Just tab
--   
-- -- holds if and only if both of -- --
--   ta = fmap fst tab
--   tb = fmap snd tab
--   
-- -- holds. Otherwise, zipMatch ta tb = Nothing. -- -- For example, the type signature of zipMatch on the list -- Functor [] reads as follows: -- --
--   zipMatch :: [a] -> [b] -> Maybe [(a,b)]
--   
-- -- zipMatch as bs returns Just (zip as bs) if the -- lengths of two given lists are same, and returns Nothing -- otherwise. -- --

Example

-- --
--   >>> zipMatch [1, 2, 3] ['a', 'b', 'c']
--   Just [(1,'a'),(2,'b'),(3,'c')]
--   
--   >>> zipMatch [1, 2, 3] ['a', 'b']
--   Nothing
--   
zipMatch :: Matchable t => t a -> t b -> Maybe (t (a, b)) -- | Match two structures. If they match, zip them with given function -- (a -> b -> Maybe c). Passed function can make whole -- match fail by returning Nothing. -- -- A definition of zipMatchWith must satisfy: -- -- -- -- If t is also Traversable, the last condition can be -- dropped and the equation can be stated without using tc. -- --
--   zipMatchWith f ta tb = traverse (uncurry f) tab
--   
-- -- zipMatch can be defined in terms of zipMatchWith. -- And if t is also Traversable, zipMatchWith -- can be defined in terms of zipMatch. When you implement both -- of them by hand, keep their relation in the way the default -- implementation is. -- --
--   zipMatch             = zipMatchWith (curry pure)
--   zipMatchWith f ta tb = zipMatch ta tb >>= traverse (uncurry f)
--   
zipMatchWith :: Matchable t => (a -> b -> Maybe c) -> t a -> t b -> Maybe (t c) -- |
--   zipzipMatch = zipMatchWith zipMatch
--   
zipzipMatch :: (Matchable t, Matchable u) => t (u a) -> t (u b) -> Maybe (t (u (a, b))) -- | Matchable t implies Functor t. It is not recommended -- to implement fmap through this function, so it is named -- fmapRecovered but not fmapDefault. fmapRecovered :: Matchable t => (a -> b) -> t a -> t b -- | Matchable t implies Eq a => Eq (t a). eqDefault :: (Matchable t, Eq a) => t a -> t a -> Bool -- | Matchable t implies Eq1 t. liftEqDefault :: Matchable t => (a -> b -> Bool) -> t a -> t b -> Bool -- | An instance of Matchable can be implemened through GHC Generics. You -- only need to do two things: Make your type Functor and -- Generic1. -- --

Example

-- --
--   >>> :set -XDeriveFunctor
--   
--   >>> :set -XDeriveGeneric
--   
--   >>> :{
--     data MyTree label a = Leaf a | Node label [MyTree label a]
--       deriving (Show, Read, Eq, Ord, Functor, Generic1)
--   :}
--   
-- -- Then you can use genericZipMatchWith to implement -- zipMatchWith method. You also need Eq1 instance, but -- liftEqDefault is provided. -- --
--   >>> :{
--     instance (Eq label) => Matchable (MyTree label) where
--       zipMatchWith = genericZipMatchWith
--     instance (Eq label) => Eq1 (MyTree label) where
--       liftEq = liftEqDefault
--     :}
--   
-- --
--   >>> zipMatch (Node "foo" [Leaf 1, Leaf 2]) (Node "foo" [Leaf 'a', Leaf 'b'])
--   Just (Node "foo" [Leaf (1,'a'),Leaf (2,'b')])
--   
--   >>> zipMatch (Node "foo" [Leaf 1, Leaf 2]) (Node "bar" [Leaf 'a', Leaf 'b'])
--   Nothing
--   
--   >>> zipMatch (Node "foo" [Leaf 1]) (Node "foo" [])
--   Nothing
--   
class Matchable' t -- | zipMatchWith via Generics. genericZipMatchWith :: (Generic1 t, Matchable' (Rep1 t)) => (a -> b -> Maybe c) -> t a -> t b -> Maybe (t c) instance GHC.Base.Functor (Data.Matchable.FillIn b) instance GHC.Base.Applicative (Data.Matchable.FillIn b) instance Data.Matchable.Matchable' GHC.Generics.V1 instance Data.Matchable.Matchable' GHC.Generics.U1 instance Data.Matchable.Matchable' GHC.Generics.Par1 instance Data.Matchable.Matchable f => Data.Matchable.Matchable' (GHC.Generics.Rec1 f) instance GHC.Classes.Eq c => Data.Matchable.Matchable' (GHC.Generics.K1 i c) instance Data.Matchable.Matchable' f => Data.Matchable.Matchable' (GHC.Generics.M1 i c f) instance (Data.Matchable.Matchable' f, Data.Matchable.Matchable' g) => Data.Matchable.Matchable' (f GHC.Generics.:+: g) instance (Data.Matchable.Matchable' f, Data.Matchable.Matchable' g) => Data.Matchable.Matchable' (f GHC.Generics.:*: g) instance (Data.Matchable.Matchable f, Data.Matchable.Matchable' g) => Data.Matchable.Matchable' (f GHC.Generics.:.: g) instance Data.Matchable.Matchable Data.Functor.Identity.Identity instance GHC.Classes.Eq k => Data.Matchable.Matchable (Data.Functor.Const.Const k) instance (Data.Matchable.Matchable f, Data.Matchable.Matchable g) => Data.Matchable.Matchable (Data.Functor.Product.Product f g) instance (Data.Matchable.Matchable f, Data.Matchable.Matchable g) => Data.Matchable.Matchable (Data.Functor.Sum.Sum f g) instance (Data.Matchable.Matchable f, Data.Matchable.Matchable g) => Data.Matchable.Matchable (Data.Functor.Compose.Compose f g) instance Data.Matchable.Matchable Data.Proxy.Proxy instance Data.Matchable.Matchable (Data.Tagged.Tagged t) instance Data.Matchable.Matchable GHC.Maybe.Maybe instance Data.Matchable.Matchable [] instance Data.Matchable.Matchable GHC.Base.NonEmpty instance GHC.Classes.Eq e => Data.Matchable.Matchable ((,) e) instance GHC.Classes.Eq e => Data.Matchable.Matchable (Data.Either.Either e) instance GHC.Classes.Eq k => Data.Matchable.Matchable (Data.Map.Internal.Map k) instance Data.Matchable.Matchable Data.IntMap.Internal.IntMap instance Data.Matchable.Matchable Data.Tree.Tree instance Data.Matchable.Matchable Data.Sequence.Internal.Seq instance Data.Matchable.Matchable Data.Vector.Vector instance (GHC.Classes.Eq k, Data.Hashable.Class.Hashable k) => Data.Matchable.Matchable (Data.HashMap.Base.HashMap k)