-
Notifications
You must be signed in to change notification settings - Fork 88
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Implement Data.Reflectable * Use ordering type instead of the primitive kind * Add tests for reflection and reification Co-authored-by: Thomas Honeyman <hello@thomashoneyman.com>
- Loading branch information
1 parent
eff3517
commit 5f1ba9f
Showing
4 changed files
with
91 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
// module Data.Reflectable | ||
|
||
export const unsafeCoerce = function (arg) { | ||
return arg; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
module Data.Reflectable | ||
( class Reflectable | ||
, class Reifiable | ||
, reflectType | ||
, reifyType | ||
) where | ||
|
||
import Data.Ord (Ordering) | ||
import Type.Proxy (Proxy(..)) | ||
|
||
-- | A type-class for reflectable types. | ||
-- | | ||
-- | Instances for the following kinds are solved by the compiler: | ||
-- | * Boolean | ||
-- | * Int | ||
-- | * Ordering | ||
-- | * Symbol | ||
class Reflectable :: forall k. k -> Type -> Constraint | ||
class Reflectable v t | v -> t where | ||
-- | Reflect a type `v` to its term-level representation. | ||
reflectType :: Proxy v -> t | ||
|
||
-- | A type class for reifiable types. | ||
-- | | ||
-- | Instances of this type class correspond to the `t` synthesized | ||
-- | by the compiler when solving the `Reflectable` type class. | ||
class Reifiable :: Type -> Constraint | ||
class Reifiable t | ||
|
||
instance Reifiable Boolean | ||
instance Reifiable Int | ||
instance Reifiable Ordering | ||
instance Reifiable String | ||
|
||
-- local definition for use in `reifyType` | ||
foreign import unsafeCoerce :: forall a b. a -> b | ||
|
||
-- | Reify a value of type `t` such that it can be consumed by a | ||
-- | function constrained by the `Reflectable` type class. For | ||
-- | example: | ||
-- | | ||
-- | ```purs | ||
-- | twiceFromType :: forall v. Reflectable v Int => Proxy v -> Int | ||
-- | twiceFromType = (_ * 2) <<< reflectType | ||
-- | | ||
-- | twiceOfTerm :: Int | ||
-- | twiceOfTerm = reifyType 21 twiceFromType | ||
-- | ``` | ||
reifyType :: forall t r. Reifiable t => t -> (forall v. Reflectable v t => Proxy v -> r) -> r | ||
reifyType s f = coerce f { reflectType: \_ -> s } Proxy | ||
where | ||
coerce | ||
:: (forall v. Reflectable v t => Proxy v -> r) | ||
-> { reflectType :: Proxy _ -> t } | ||
-> Proxy _ | ||
-> r | ||
coerce = unsafeCoerce |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters