!1/&      !"#$%None4>HUVf/A  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 &S, 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.  '      !"#$%&'()*+(matchable-0.1.1.1-JeuRsXU9Qkx5vS0Awpf0VZData.Matchable Matchable' MatchablezipMatch zipMatchWith 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.Traversable Traversable