magic-tyfams: Write plugins for magic type families with ease

[ bsd3, compiler-plugin, library ] [ Propose Tags ]

Please see the README on GitHub at https://github.com/isovector/type-sets/tree/master/magic-tyfams#readme


[Skip to Readme]
Versions [faq] 0.1.0.0, 0.1.0.1, 0.1.0.2, 0.1.1.0
Change log ChangeLog.md
Dependencies base (>=4.7 && <5), ghc (>=8.6.3 && <8.8), ghc-tcplugins-extra (==0.3.*), syb (==0.7.*) [details]
License BSD-3-Clause
Copyright 2019 Sandy Maguire
Author Sandy Maguire
Maintainer sandy@sandymaguire.me
Category Compiler Plugin
Home page https://github.com/https://github.com/isovector/type-sets/tree/master/magic-tyfams#readme
Bug tracker https://github.com/https://github.com/isovector/type-sets/tree/master/magic-tyfams/issues
Source repo head: git clone https://github.com/https://github.com/isovector/type-sets/tree/master/magic-tyfams
Uploaded by isovector at Sun Aug 11 15:58:34 UTC 2019
Distributions NixOS:0.1.1.0
Downloads 152 total (45 in the last 30 days)
Rating (no votes yet) [estimated by rule of succession]
Your Rating
  • λ
  • λ
  • λ
Status Hackage Matrix CI
Docs available [build log]
Last success reported on 2019-08-11 [all 1 reports]

Modules

[Index] [Quick Jump]

Downloads

Maintainer's Corner

For package maintainers and hackage trustees


Readme for magic-tyfams-0.1.1.0

[back to package description]

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.