úÎ!HxE˜0      !"#$%&'()*+,-./SafeÕ matchableCContainers that allows exact structural matching of two containers. Bimatchable is 0 -version of  Matchable;. It can compare and zip containers with two parameters. matchable is to  what 1 is to 2.VDecides if two structures match exactly. If they match, return zipped version of them.LawForall  x :: t a b,  y :: t a' b', z :: t (a,a') (b,b'), bizipMatch x y = Just zholds if and only if both of 'x = bimap fst fst z y = bimap snd snd zholds. Otherwise, bizipMatch x y = Nothing.ExamplebizipMatch (Left 1) (Left 'a')Just (Left (1,'a'))"bizipMatch (Right 1) (Right False)Just (Right (1,False))!bizipMatch (Left 1) (Right False)Nothing matchable is to  what 1 is to 2.EMatch 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.LawFor any Kx :: t a b y :: t a' b' f :: a -> a' -> Maybe a'' g :: b -> b' -> Maybe b'' must satisfy the following.If there is a pair &(z :: t (a,a') (b,b'), w :: t a'' b'')P such that fulfills all of the following three conditions, then bizipMatchWith f g x y = Just w.  x = bimap fst fst z y = bimap snd snd z 3bimap (uncurry f) (uncurry g) z = bimap Just Just wIf there are no such pair,  bizipMatchWith f g x y = Nothing.None4>HUVfEL  matchablepAn 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]5 deriving (Show, Read, Eq, Ord, Functor, Generic1):}Then you can use genericZipMatchWith to implement  zipMatchWith method. You also need Eq1 instance, but  is provided.:{7 instance (Eq label) => Matchable (MyTree label) where& zipMatchWith = genericZipMatchWith1 instance (Eq label) => Eq1 (MyTree label) where liftEq = liftEqDefault :}HzipMatch (Node "foo" [Leaf 1, Leaf 2]) (Node "foo" [Leaf 'a', Leaf 'b'])-Just (Node "foo" [Leaf (1,'a'),Leaf (2,'b')])HzipMatch (Node "foo" [Leaf 1, Leaf 2]) (Node "bar" [Leaf 'a', Leaf 'b'])Nothing.zipMatch (Node "foo" [Leaf 1]) (Node "foo" [])Nothing  matchableCContainers that allows exact structural matching of two containers.  matchableVDecides if two structures match exactly. If they match, return zipped version of them. zipMatch ta tb = Just tabholds if and only if both of #ta = fmap fst tab tb = fmap snd tabholds. 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  matchableDMatch 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   must satisfy:If there is a pair  (tab, tc)A such that fulfills all following three conditions, then zipMatchWith f ta tb = Just tc.  ta = fmap fst tab tb = fmap snd tab #fmap (uncurry f) tab = fmap Just tcIf there are no such pair, zipMatchWith f ta tb = Nothing.If t is also 3S, the last condition can be dropped and the equation can be stated without using tc. /zipMatchWith f ta tb = traverse (uncurry f) tabzipMatch can be defined in terms of  zipMatchWith . And if t is also  Traversable,  zipMatchWith can be defined in terms of zipMatchl. When you implement both of them by hand, keep their relation in the way the default implementation is. ozipMatch = zipMatchWith (curry pure) zipMatchWith f ta tb = zipMatch ta tb >>= traverse (uncurry f) matchable #zipzipMatch = zipMatchWith zipMatch matchable Matchable t implies  Functor t(. It is not recommended to implement fmap* through this function, so it is named  fmapRecovered but not  fmapDefault. matchable Matchable t implies Eq a => Eq (t a). matchable Matchable t implies Eq1 t. matchablezipMatchWith via Generics.   4      !"#$%&'()*+,-./01234534637839:;&matchable-0.1.2-KlXqdQbcAtv2dwaFlUDy0VData.BimatchableData.MatchablezipMatch zipMatchWith Bimatchable bizipMatchbizipMatchWithbimapRecovered eq2DefaultliftEq2Default$fBimatchableTagged$fBimatchableConst$fBimatchable(,)$fBimatchableEither Matchable' Matchable zipzipMatch fmapRecovered eqDefault liftEqDefaultgenericZipMatchWith$fMatchableHashMap$fMatchableVector$fMatchableSeq$fMatchableTree$fMatchableIntMap$fMatchableMap$fMatchableEither$fMatchable(,)$fMatchableNonEmpty $fMatchable[]$fMatchableMaybe$fMatchableTagged$fMatchableProxy$fMatchableCompose$fMatchableSum$fMatchableProduct$fMatchableConst$fMatchableIdentity$fMatchable':.:$fMatchable':*:$fMatchable':+:$fMatchable'M1$fMatchable'K1$fMatchable'Rec1$fMatchable'Par1$fMatchable'U1$fMatchable'V1$fApplicativeFillIn$fFunctorFillInbaseData.Bifunctor BifunctorbimapGHC.BasefmapData.Traversable Traversable