| 36 | |

| 37 | Here is a second example from [http://www.reddit.com/r/haskell/comments/1kmods/patternsynonyms_ghc_trac/ pigworker on Reddit]. |

| 38 | Your basic sums-of-products functors can be built from this kit. |

| 39 | {{{ |

| 40 | newtype K a x = K a |

| 41 | newtype I x = I x |

| 42 | newtype (:+:) f g x = Sum (Either (f x) (g x)) |

| 43 | newtype (:*:) f g x = Prod (f x, g x) |

| 44 | }}} |

| 45 | and then you can make recursive datatypes via |

| 46 | {{{ |

| 47 | newtype Fix f = In (f (Fix f)) |

| 48 | }}} |

| 49 | e.g., |

| 50 | {{{ |

| 51 | type Tree = Fix (K () :+: (I :*: I)) |

| 52 | }}} |

| 53 | and you can get useful generic operations cheaply because the functors in the kit are all `Traversable`, admit a partial zip operation, etc. |

| 54 | |

| 55 | You can define friendly constructors for use in expressions |

| 56 | {{{ |

| 57 | leaf :: Tree |

| 58 | leaf = In (Sum (Left (K ()))) |

| 59 | node :: Tree -> Tree -> Tree |

| 60 | node l r = In (Sum (Right (Prod (I l, I r)))) |

| 61 | }}} |

| 62 | but any `Tree`-specific pattern matching code you write will be wide and obscure. Turning these definitions into pattern synonyms means you can have both readable type-specific programs and handy generics without marshalling your data between views. |