MyNixOS website logo
Description

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.

Metadata

Version

0.1.1.0

Platforms (75)

    Darwin
    FreeBSD
    Genode
    GHCJS
    Linux
    MMIXware
    NetBSD
    none
    OpenBSD
    Redox
    Solaris
    WASI
    Windows
Show all
  • aarch64-darwin
  • aarch64-genode
  • aarch64-linux
  • aarch64-netbsd
  • aarch64-none
  • aarch64_be-none
  • arm-none
  • armv5tel-linux
  • armv6l-linux
  • armv6l-netbsd
  • armv6l-none
  • armv7a-darwin
  • armv7a-linux
  • armv7a-netbsd
  • armv7l-linux
  • armv7l-netbsd
  • avr-none
  • i686-cygwin
  • i686-darwin
  • i686-freebsd
  • i686-genode
  • i686-linux
  • i686-netbsd
  • i686-none
  • i686-openbsd
  • i686-windows
  • javascript-ghcjs
  • loongarch64-linux
  • m68k-linux
  • m68k-netbsd
  • m68k-none
  • microblaze-linux
  • microblaze-none
  • microblazeel-linux
  • microblazeel-none
  • mips-linux
  • mips-none
  • mips64-linux
  • mips64-none
  • mips64el-linux
  • mipsel-linux
  • mipsel-netbsd
  • mmix-mmixware
  • msp430-none
  • or1k-none
  • powerpc-netbsd
  • powerpc-none
  • powerpc64-linux
  • powerpc64le-linux
  • powerpcle-none
  • riscv32-linux
  • riscv32-netbsd
  • riscv32-none
  • riscv64-linux
  • riscv64-netbsd
  • riscv64-none
  • rx-none
  • s390-linux
  • s390-none
  • s390x-linux
  • s390x-none
  • vc4-none
  • wasm32-wasi
  • wasm64-wasi
  • x86_64-cygwin
  • x86_64-darwin
  • x86_64-freebsd
  • x86_64-genode
  • x86_64-linux
  • x86_64-netbsd
  • x86_64-none
  • x86_64-openbsd
  • x86_64-redox
  • x86_64-solaris
  • x86_64-windows