@hackage magic-tyfams0.1.1.0

Write plugins for magic type families with ease

magic-tyfams

Hackage

Dedication

G.O.B.: Two drowned white doves from "Flowers to Doves," a rabbit from "Doves to Rabbit," also drowned. These were mice...

Tobias: From "Rabbit to Mice?"

G.O.B.: No. That can't be done. No, these were a part of something I call mice-cellaneous: "Mouse in Purse." "Mouse in Drink." Here's a mouse, now it's gone...

--Arrested Development

Overview

magic-tyfams writes the annoying parts of GHC plugins so you don't have to. It provides a convenient interface for implementing magical type families.

For example, consider the following definition in mypackage of an always-stuck type family:

module Some.Module where

type family CmpType (a :: k) (b :: k) :: Ordering

We can generate a plugin that will solve this:

module Some.Plugin where

plugin :: Plugin
plugin = magicTyFamPlugin "mypackage"
                          "Some.Module"
                          "CmpType" $
  withStuckSemantics $ \[_k, a, b] ->
    pure $ promoteOrdering $ nonDetCmpType a b


promoteOrdering :: Ordering -> Type
promoteOrdering = flip mkTyConApp [] . \case
   LT -> promotedLTDataCon
   EQ -> promotedEQDataCon
   GT -> promotedGTDataCon

Enabling this plugin via -fplugin=Some.Plugin will now automagically solve CmpType! Nice!

{-# OPTIONS_GHC -fplugin=Some.Plugin #-}

import Proxy

-- compiles just fine!
test :: Proxy (CmpType Int Int) -> Proxy 'EQ
test = id

Acknowledgments

Thanks to Christiaan Baaij and Matt Pickering for their indispensable help convincing GHC to do the right thing here.