|
| 1 | +module Type.Data.Ordering |
| 2 | + ( kind Ordering |
| 3 | + , LT |
| 4 | + , EQ |
| 5 | + , GT |
| 6 | + , OProxy(..) |
| 7 | + , class IsOrdering |
| 8 | + , reflectOrdering |
| 9 | + , reifyOrdering |
| 10 | + , class AppendOrdering |
| 11 | + , appendOrdering |
| 12 | + , class InvertOrdering |
| 13 | + , invertOrdering |
| 14 | + ) where |
| 15 | + |
| 16 | +import Data.Ordering (Ordering(..)) |
| 17 | + |
| 18 | +foreign import kind Ordering |
| 19 | +foreign import data LT :: Ordering |
| 20 | +foreign import data EQ :: Ordering |
| 21 | +foreign import data GT :: Ordering |
| 22 | + |
| 23 | +-- | Value proxy for `Ordering` types |
| 24 | +data OProxy (ordering :: Ordering) = OProxy |
| 25 | + |
| 26 | +-- | Class for reflecting a type level `Ordering` at the value level |
| 27 | +class IsOrdering (ordering :: Ordering) where |
| 28 | + reflectOrdering :: OProxy ordering -> Ordering |
| 29 | + |
| 30 | +instance isOrderingLT :: IsOrdering LT where reflectOrdering _ = LT |
| 31 | +instance isOrderingEQ :: IsOrdering EQ where reflectOrdering _ = EQ |
| 32 | +instance isOrderingGT :: IsOrdering GT where reflectOrdering _ = GT |
| 33 | + |
| 34 | +-- | Use a value level `Ordering` as a type-level `Ordering` |
| 35 | +reifyOrdering :: forall r. Ordering -> (forall o. IsOrdering o => OProxy o -> r) -> r |
| 36 | +reifyOrdering LT f = f (OProxy :: OProxy LT) |
| 37 | +reifyOrdering EQ f = f (OProxy :: OProxy EQ) |
| 38 | +reifyOrdering GT f = f (OProxy :: OProxy GT) |
| 39 | + |
| 40 | +-- | Append two `Ordering` types together |
| 41 | +-- | Reflective of the semigroup for value level `Ordering` |
| 42 | +class AppendOrdering (lhs :: Ordering) |
| 43 | + (rhs :: Ordering) |
| 44 | + (output :: Ordering) | |
| 45 | + lhs -> rhs output |
| 46 | +instance appendOrderingLT :: AppendOrdering LT rhs LT |
| 47 | +instance appendOrderingEQ :: AppendOrdering EQ rhs rhs |
| 48 | +instance appendOrderingGT :: AppendOrdering GT rhs GT |
| 49 | + |
| 50 | +appendOrdering :: forall l r o. AppendOrdering l r o => OProxy l -> OProxy r -> OProxy o |
| 51 | +appendOrdering _ _ = OProxy |
| 52 | + |
| 53 | +-- | Invert an `Ordering` |
| 54 | +class InvertOrdering (ordering :: Ordering) |
| 55 | + (result :: Ordering) | |
| 56 | + ordering -> result |
| 57 | +instance invertOrderingLT :: InvertOrdering LT GT |
| 58 | +instance invertOrderingEQ :: InvertOrdering EQ EQ |
| 59 | +instance invertOrderingGT :: InvertOrdering GT LT |
| 60 | + |
| 61 | +invertOrdering :: forall i o. InvertOrdering i o => OProxy i -> OProxy o |
| 62 | +invertOrdering _ = OProxy |
0 commit comments