rearrangements
February 27, 2025 ยท View on GitHub
This repo takes the rearrangements part of rearrange for easy inclusion into other projects. New TemplateHaskell versions of rearrangements have also been added.
rearrangements via typeclasses
To perform rearrangements like in the original rearrange work, it suffices to import the following two modules:
Data.HListprovides a simple heterogeneous list implementation.Rearrange.Typeclassprovides a typeclass-based implementation of rearrangements.
Then we write rearrangements using rearr and rearrDel:
import Data.HList
import Rearrange.Typeclass
list :: HList '[Int, Bool, Int]
list = 3 :+: True :+: 4 :+: HNil
list' :: HList '[Int, Int]
list' = let (res, spare) = rearrDel list in res
-- res = 3 :+: 4 :+: HNil
-- spare = True :+: HNil
list'' :: HList '[Bool, Int]
list'' = rearr list
-- will return True :+: 3 :+: HNil
We can also apply rearrangements to alternative structures by specifying instances of Rearrangeable and RearrangeableStar for them. The latter allows for rearrangements of nested structures, like rearranging HList '[HList '[Bool, Int], ()] to HList '[Bool, HList '[(), Int]], but as a result requires those structures to be of kind Type. This is useful for structures which are isomorphic to HList, so that we do not need to convert to and from HLists to use rearrange. More details can be found in Rearrange.Rearrangeable.
rearrangements via TemplateHaskell
The Rearrange.TH module provides a typed TemplateHaskell version of these rearrangements. These are used near identically to rearrangements with type classes, but with slightly different names:
import Data.HList
import Rearrange.TH
list :: HList '[Int, Bool, Int]
list = 3 :+: True :+: 4 :+: HNil
list' :: HList '[Int, Int]
list' =
let (res, spare) = $$(rearrangeDelTH @'[Int, Bool, Int] @'[Int, Int]) list
in res
-- res = 3 :+: 4 :+: HNil
-- spare = True :+: HNil
list'' :: HList '[Bool, Int]
list'' = $$(rearrangeTH @'[Int, Bool, Int] @'[Bool, Int]) list
-- will return True :+: 3 :+: HNil
Note that the TemplateHaskell versions require type annotations: this is due to a limitation in Typed TemplateHaskell.