| Safe Haskell | None |
|---|---|
| Language | Haskell2010 |
Overloaded.Plugin
Description
Overloaded plugin, which makes magic possible.
Documentation
Overloaded plugin.
To enable plugin put the following at top of the module:
{-# OPTIONS -fplugin=Overloaded -fplugin-opt=Overloaded:Symbols #-}
At least one option is required, multiple can given
either using multiple -fplugin-opt options, or by separating options
with colon:
{-# OPTIONS -fplugin=Overloaded -fplugin-opt=Overloaded:Symbols:Numerals #-}
Options also take optional desugaring names, for example
{-# OPTIONS -fplugin=Overloaded -fplugin-opt=Overloaded:Labels=Data.Generics.ProductFields.field #-}
to desugar OverloadedLabels directly into field from generics-lens (no need to import orphan instance!)
Supported options
Symbolsdesugars literal strings tofromSymbol@symStringsworks like built-inOverloadedStrings(but you can use different method thanfromString)Numeralsdesugars literal numbers tofromNumeral@natNaturalsdesugars literal numbers to(i.e. likefromNaturalnatfromString)Charsdesugars literal characters to. Note: there isn't type-level alternative: we cannot promotefromCharscChars.Listsis not like built-inOverloadedLists, but desugars explicit lists toconsandnilIfdesugarsif-expressions toifteb t eLabelsworks like built-inOverloadedLabels(you should enableOverloadedLabelsso parser recognises the syntax)TypeNatsandTypeSymbolsdesugar type-level literals intoandFromNatrespectively.FromTypeSymbol
Known limitations
- Doesn't desugar inside patterns
RecordFields
WARNING the type-checker plugin is experimental, it's adviced to use
{-# OPTIONS_GHC -ddump-simpl #-}
to avoid surprising segfaults.
Usage
{-# OPTIONS -fplugin=Overloaded -fplugin-opt=Overloaded:RecordFields #-}
Implementation bits
See Note [HasField instances] in ClsInst, the behavior of this plugin is similar.
The HasField class is defined in GHC.Records.Compat module of record-hasfield package:
classHasField{k} x r a | x r -> a wherehasField:: r -> (a -> r, a)
Suppose we have
data R y = MkR { foo :: [y] }
and foo in scope. We will solve constraints like
HasField "foo" (R Int) a
by emitting a new wanted constraint
[Int] ~# a
and building a HasField dictionary out of selector foo appropriately cast.
Idiom brackets from TemplateHaskellQuotes
{-# LANGUAGE TemplateHaskellQuotes #-}
{-# OPTIONS_GHC -fplugin=Overloaded -fplugin-opt=Overloaded:IdiomBrackets #-}
data Tree a
= Leaf a
| Branch (Tree a) (Tree a)
deriving (Show)
instance Functor Tree where
fmap f (Leaf x) = Leaf (f x)
fmap f (Branch l r) = Branch (fmap f l) (fmap f r)
instance Traversable Tree where
traverse f (Leaf x) = [| Leaf (f x) |]
traverse f (Branch l r) = [| Branch (traverse f l) (traverse f r) |]