Last active
August 29, 2015 14:04
-
-
Save dorchard/4df935ebad0807c47b80 to your computer and use it in GitHub Desktop.
type level implicit parameters example (speculation)
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
Consider a data type representing syntax trees. | |
> data Expr = BinOp Expr Expr | Unop Expr | |
> data Stmt = Seq Stmt Stmt | Assign String Expr | |
Let's say I want this in a module, but I also want to be able to arbitrarily extend this AST type | |
in modules that import it. So, I add an extra constructor and a type parameter | |
to all the data type definitions: | |
> data Expr ext = BinOp (Expr ext) (Expr ext) | Unop (Expr ext) | Ext ext | |
> data Stmt ext = Seq (Stmt ext) (Stmt ext) | Assign String (Expr ext) | |
However, the larger the type structure, the more annoying it is to add the 'ext' parameter everywhere that | |
needs it. At the value-level, there is already a useful solution to this 'extension'/'configuration' | |
problem for value definitions using the *implicit parameters* extension. But this is not available at the type level. | |
Let's imagine it *is* available. Then we could write something like: | |
> data Expr = BinOp Expr Expr | Unop Expr | Ext ?ext | |
> data Stmt = Seq Stmt Stmt | Assign String Expr | |
The question mark signifies that '?ext' is an implicit (type) parameter. | |
Then we get the following kinds on our types: | |
> *Main> :k Expr | |
> Expr :: (?ext :: *) => * -> * | |
> *Main> :k Stmt | |
> Stmt :: (?ext :: *) => * -> * | |
We can 'discharge' the implicit parameter constraint by fixing the type with | |
a local type synonym: | |
> *Main> Assign "v" (Ext 1) where type ?ext = Int | |
> Assign "v" (Ext 1) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment