Safe Haskell | None |
---|---|
Language | Haskell2010 |
Overloaded*
language extensions as a source plugin.
Synopsis
- plugin :: Plugin
- class FromSymbol (s :: Symbol) a where
- fromSymbol :: a
- class FromNumeral (n :: Nat) a where
- fromNumeral :: a
- defaultFromNumeral :: forall n a. (KnownNat n, Integral a) => a
- class FromNatural a where
- fromNatural :: Natural -> a
- class FromChar a where
- class Nil a where
- nil :: a
- class Cons x ys zs | zs -> x ys where
- cons :: x -> ys -> zs
- class ToBool b where
- ifte :: ToBool b => b -> a -> a -> a
- class IsCodeLabel (sym :: Symbol) a where
- codeFromLabel :: SpliceQ a
- class IsCodeString a where
- codeFromString :: String -> SpliceQ a
- class FromNatC a where
- class FromTypeSymbolC a where
- type FromTypeSymbol (s :: Symbol) :: a
- data DoMethod
- type Pure = 'Pure
- type Then = 'Then
- type Bind = 'Bind
- class Monad' (method :: DoMethod) (ty :: Type) where
- monad :: ty
- class Category (cat :: k -> k -> Type)
- identity :: Category cat => cat a a
- (%%) :: Category cat => cat b c -> cat a b -> cat a c
- class Category cat => CartesianCategory (cat :: k -> k -> Type) where
- class Category cat => CocartesianCategory (cat :: k -> k -> Type) where
- class (CartesianCategory cat, CocartesianCategory cat) => BicartesianCategory cat where
- class CartesianCategory cat => CCC (cat :: k -> k -> Type) where
- type Exponential cat :: k -> k -> k
- eval :: cat (Product cat (Exponential cat a b) a) b
- transpose :: cat (Product cat a b) c -> cat a (Exponential cat b c)
Plugin
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
Symbols
desugars literal strings tofromSymbol
@symStrings
works like built-inOverloadedStrings
(but you can use different method thanfromString
)Numerals
desugars literal numbers tofromNumeral
@natNaturals
desugars literal numbers to
(i.e. likefromNatural
natfromString
)Chars
desugars literal characters to
. Note: there isn't type-level alternative: we cannot promotefromChars
cChar
sLists
is not like built-inOverloadedLists
, but desugars explicit lists tocons
andnil
If
desugarsif
-expressions toifte
b t eUnit
desugars()
-expressions to
(but you can use different method, e.g.nil
boring
from Data.Boring)Labels
works like built-inOverloadedLabels
(you should enableOverloadedLabels
so parser recognises the syntax)TypeNats
andTypeSymbols
desugar type-level literals into
andFromNat
respectivelyFromTypeSymbol
Do
desugar in Local Do fashion. See examples.Categories
changeArrows
desugaring to use "correct" category classes.CodeLabels
desugarsOverloadedLabels
into Typed Template Haskell splicesCodeStrings
desugars string literals into Typed Template Haskell splicesRebindableApplication
changes how juxtaposition is interpretedOverloadedConstructors
allows you to use overloaded constructor names!
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 wherefmap
f (Leaf x) = Leaf (f x)fmap
f (Branch l r) = Branch (fmap
f l) (fmap
f r) instance Traversable Tree wheretraverse
f (Leaf x) = [| Leaf (f x) |]traverse
f (Branch l r) = [| Branch (traverse
f l) (traverse
f r) |]
RebindableApplication
Converts all f x
applications into (f $ x)
with whatever $
is in scope.
{-# OPTIONS -fplugin=Overloaded -fplugin-opt=Overloaded:RebindableApplication #-}
let f = pure ((+) :: Int -> Int -> Int)
x = Just 1
y = Just 2
z = let ($) = (<*>
) in f x y
in z
Overloaded:Symbols
class FromSymbol (s :: Symbol) a where Source #
Another way to desugar overloaded string literals using this class.
A string literal "example"
is desugared to
fromSymbol
@"example"
Enabled with:
{-# OPTIONS -fplugin=Overloaded -fplugin-opt=Overloaded:Symbols #-}
fromSymbol :: a Source #
Instances
(KnownNat y, KnownNat m, KnownNat d, ParseDay s ~ '(y, m, d)) => FromSymbol s Day Source # | |
Defined in Overloaded.Symbols fromSymbol :: Day Source # | |
(KnownSymbol s, SeqList (ToList s)) => FromSymbol s ByteString Source # | |
Defined in Overloaded.Symbols | |
(KnownSymbol s, SeqList (ToList s)) => FromSymbol s ByteString Source # | |
Defined in Overloaded.Symbols | |
KnownSymbol s => FromSymbol s Text Source # | |
Defined in Overloaded.Symbols fromSymbol :: Text Source # | |
KnownSymbol s => FromSymbol s Text Source # | |
Defined in Overloaded.Symbols fromSymbol :: Text Source # | |
(KnownSymbol s, a ~ Char) => FromSymbol s [a] Source # | |
Defined in Overloaded.Symbols fromSymbol :: [a] Source # |
Overloaded:Strings
See Data.String for fromString
.
Overloaded:Numerals
class FromNumeral (n :: Nat) a where Source #
Another way to desugar numerals.
A numeric literal 123
is desugared to
fromNumeral
@123
Enabled with:
{-# OPTIONS -fplugin=Overloaded -fplugin-opt=Overloaded:Numerals #-}
One can do type-level computations with this.
fromNumeral :: a Source #
Instances
defaultFromNumeral :: forall n a. (KnownNat n, Integral a) => a Source #
Default implementation of fromNumeral
.
Usage example:
instance (KnownNat
n, ...) =>FromNumeral
n MyType wherefromNumeral
=defaultFromNumeral
@n
Overloaded:Naturals
class FromNatural a where Source #
fromNatural :: Natural -> a Source #
Instances
FromNatural Integer Source # | |
Defined in Overloaded.Naturals fromNatural :: Natural -> Integer Source # | |
FromNatural Natural Source # | |
Defined in Overloaded.Naturals fromNatural :: Natural -> Natural Source # |
Overloaded:Chars
Overloaded:Lists
Class for nil, []
See test-suite for ways to define instances for Map
.
There are at-least two-ways.
Instances
Nil IntSet Source # | Since: 0.1.3 |
Defined in Overloaded.Lists | |
Nil [a] Source # | |
Defined in Overloaded.Lists | |
Nil (IntMap v) Source # | Since: 0.2 |
Defined in Overloaded.Lists | |
Nil (Seq a) Source # | Since: 0.2 |
Defined in Overloaded.Lists | |
Nil (Set a) Source # | Since: 0.1.3 |
Defined in Overloaded.Lists | |
Nil (RAList a) Source # | |
Defined in Overloaded.Lists | |
Nil (Map k v) Source # | Since: 0.2 |
Defined in Overloaded.Lists | |
b ~ 'BZ => Nil (RAVec b a) Source # | |
Defined in Overloaded.Lists | |
n ~ 'Z => Nil (Vec n a) Source # | |
Defined in Overloaded.Lists | |
xs ~ ('[] :: [k]) => Nil (NP f xs) Source # | |
Defined in Overloaded.Lists | |
xs ~ ('[] :: [[k]]) => Nil (POP f xs) Source # | |
Defined in Overloaded.Lists |
class Cons x ys zs | zs -> x ys where Source #
Class for Cons :
.
Instances
Cons Int IntSet IntSet Source # | Since: 0.1.3 |
(a ~ b, a ~ c) => Cons a (RAList b) (NERAList c) Source # | |
(a ~ b, a ~ c) => Cons a (RAList b) (RAList c) Source # | |
(a ~ b, b ~ c) => Cons a (Seq b) (Seq c) Source # | Since: 0.2 |
(Ord a, a ~ b, b ~ c) => Cons a (Set b) (Set c) Source # | Since: 0.1.3 |
(a ~ b, b ~ c) => Cons a [b] (NonEmpty c) Source # | |
Defined in Overloaded.Lists | |
(a ~ b, b ~ c) => Cons a [b] [c] Source # | |
Defined in Overloaded.Lists | |
(bp ~ Pred b, b ~ Succ' bp) => Cons a (RAVec bp a) (NERAVec b a) Source # | |
(b ~ 'BP bb, bp ~ Pred bb, bb ~ Succ' bp) => Cons a (RAVec bp a) (RAVec b a) Source # | |
(a ~ b, b ~ c, m ~ 'S n) => Cons a (Vec n b) (Vec m c) Source # | |
(f ~ g, g ~ h, xxs ~ (x ': xs)) => Cons (f x) (NP g xs) (NP h xxs) Source # | |
(i ~ Int, a ~ b, b ~ c) => Cons (i, a) (IntMap b) (IntMap c) Source # | Since: 0.2 |
(Ord k, k ~ k1, k ~ k2, v ~ v1, v ~ v2) => Cons (k, v) (Map k1 v1) (Map k2 v2) Source # | Since: 0.2 |
(f ~ g, g ~ h, xsxss ~ (xs ': xss)) => Cons (NP f xs) (POP g xss) (POP h xsxss) Source # | |
Overloaded:If
Overloaded:Labels
See GHC.OverloadedLabels for fromLabel
.
Overloaded:CodeLabels
class IsCodeLabel (sym :: Symbol) a where Source #
Class for auto-spliced labels
The labels #lbl
is desugared into $$(codeFromlabel @"lbl")
splice.
{-# OPTIONS -fplugin=Overloaded -fplugin-opt=Overloaded:CodeLabels #-}
This feature is not very usable, see https://gitlab.haskell.org/ghc/ghc/-/issues/18211
codeFromLabel :: SpliceQ a Source #
Overloaded:CodeStrings
class IsCodeString a where Source #
Class for auto-spliced string literals
The string literals "beer"
is desugared into $$(codeFromString @"beer")
splice.
{-# OPTIONS -fplugin=Overloaded -fplugin-opt=Overloaded:CodeLabels #-}
This feature is not very usable, see https://gitlab.haskell.org/ghc/ghc/-/issues/18211
codeFromString :: String -> SpliceQ a Source #
Instances
IsCodeString ByteString Source # | |
Defined in Overloaded.CodeStrings codeFromString :: String -> SpliceQ ByteString Source # | |
a ~ Char => IsCodeString [a] Source # | |
Defined in Overloaded.CodeStrings codeFromString :: String -> SpliceQ [a] Source # |
Overloaded:TypeNats
A way to overload type level Nat
s.
A number type-literal 42
is desugared to
FromNat
42
Enabled with:
{-# OPTIONS -fplugin=Overloaded -fplugin-opt=Overloaded:TypeNats #-}
Instances
FromNatC Nat Source # | |
Defined in Overloaded.TypeNats | |
FromNatC Nat Source # | |
Defined in Overloaded.TypeNats | |
FromNatC Bin Source # | |
Defined in Overloaded.TypeNats | |
FromNatC BinP Source # | |
Defined in Overloaded.TypeNats |
Overloaded:TypeSymbols
class FromTypeSymbolC a Source #
A way to overload type level Symbol
s.
A symbol type-literal "example"
is desugared to
FromTypeSymbol
"example"
Enabled with:
{-# OPTIONS -fplugin=Overloaded -fplugin-opt=Overloaded:TypeSymbols #-}
type FromTypeSymbol (s :: Symbol) :: a Source #
Instances
FromTypeSymbolC Symbol Source # | |
Defined in Overloaded.TypeSymbols type FromTypeSymbol s :: a Source # |
Overloaded:Do
class Monad' (method :: DoMethod) (ty :: Type) where Source #
Instances
(ty ~ (a -> m a), Applicative m) => Monad' 'Pure ty Source # | |
Defined in Overloaded.Do | |
(ty ~ (m a -> m b -> m b), Applicative m) => Monad' 'Then ty Source # | |
Defined in Overloaded.Do | |
(ty ~ (m a -> (a -> m b) -> m b), Monad m) => Monad' 'Bind ty Source # | |
Defined in Overloaded.Do |
Overloaded:Categories
class Category (cat :: k -> k -> Type) #
A class for categories. Instances should satisfy the laws
Instances
Category (Coercion :: k -> k -> Type) | Since: base-4.7.0.0 |
Category ((:~:) :: k -> k -> Type) | Since: base-4.7.0.0 |
Category ((:~~:) :: k -> k -> Type) | Since: base-4.10.0.0 |
Category arr => Category (WrappedArrow arr :: k -> k -> Type) Source # | |
Defined in Overloaded.Categories id :: forall (a :: k0). WrappedArrow arr a a # (.) :: forall (b :: k0) (c :: k0) (a :: k0). WrappedArrow arr b c -> WrappedArrow arr a b -> WrappedArrow arr a c # | |
Category k2 => Category (Dual k2 :: k1 -> k1 -> Type) | |
Category p => Category (WrappedArrow p :: k -> k -> Type) | |
Defined in Data.Profunctor.Types id :: forall (a :: k0). WrappedArrow p a a # (.) :: forall (b :: k0) (c :: k0) (a :: k0). WrappedArrow p b c -> WrappedArrow p a b -> WrappedArrow p a c # | |
(Category p, Category q) => Category (Product p q :: k -> k -> Type) | |
(Applicative f, Category p) => Category (Tannen f p :: k -> k -> Type) | |
Category Op | |
Monad m => Category (Kleisli m :: Type -> Type -> Type) | Since: base-3.0 |
(Applicative f, Monad f) => Category (WhenMissing f :: Type -> Type -> Type) | Since: containers-0.5.9 |
Defined in Data.IntMap.Internal id :: forall (a :: k). WhenMissing f a a # (.) :: forall (b :: k) (c :: k) (a :: k). WhenMissing f b c -> WhenMissing f a b -> WhenMissing f a c # | |
Category ((->) :: Type -> Type -> Type) | Since: base-3.0 |
Defined in Control.Category | |
(Monad f, Applicative f) => Category (WhenMatched f x :: Type -> Type -> Type) | Since: containers-0.5.9 |
Defined in Data.IntMap.Internal id :: forall (a :: k). WhenMatched f x a a # (.) :: forall (b :: k) (c :: k) (a :: k). WhenMatched f x b c -> WhenMatched f x a b -> WhenMatched f x a c # | |
(Applicative f, Monad f) => Category (WhenMissing f k :: Type -> Type -> Type) | Since: containers-0.5.9 |
Defined in Data.Map.Internal id :: forall (a :: k0). WhenMissing f k a a # (.) :: forall (b :: k0) (c :: k0) (a :: k0). WhenMissing f k b c -> WhenMissing f k a b -> WhenMissing f k a c # | |
Monad f => Category (Star f :: Type -> Type -> Type) | |
(Monad f, Applicative f) => Category (WhenMatched f k x :: Type -> Type -> Type) | Since: containers-0.5.9 |
Defined in Data.Map.Internal id :: forall (a :: k0). WhenMatched f k x a a # (.) :: forall (b :: k0) (c :: k0) (a :: k0). WhenMatched f k x b c -> WhenMatched f k x a b -> WhenMatched f k x a c # |
class Category cat => CartesianCategory (cat :: k -> k -> Type) where Source #
Cartesian category is a monoidal category where monoidal product is the categorical product.
proj1 :: cat (Product cat a b) a Source #
proj2 :: cat (Product cat a b) b Source #
fanout :: cat a b -> cat a c -> cat a (Product cat b c) Source #
is written as \(\langle f, g \rangle\) in category theory literature.fanout
f g
Instances
CocartesianCategory cat => CartesianCategory (Dual cat :: k -> k -> Type) Source # | |
Defined in Overloaded.Categories | |
CartesianCategory Op Source # | |
Monad m => CartesianCategory (Kleisli m :: Type -> Type -> Type) Source # | |
Defined in Overloaded.Categories | |
CartesianCategory ((->) :: Type -> Type -> Type) Source # | |
Defined in Overloaded.Categories | |
Monad m => CartesianCategory (Star m :: Type -> Type -> Type) Source # | |
Defined in Overloaded.Categories | |
Arrow arr => CartesianCategory (WrappedArrow arr :: Type -> Type -> Type) Source # | |
Defined in Overloaded.Categories type Product (WrappedArrow arr) :: k -> k -> k Source # proj1 :: forall (a :: k) (b :: k). WrappedArrow arr (Product (WrappedArrow arr) a b) a Source # proj2 :: forall (a :: k) (b :: k). WrappedArrow arr (Product (WrappedArrow arr) a b) b Source # fanout :: forall (a :: k) (b :: k) (c :: k). WrappedArrow arr a b -> WrappedArrow arr a c -> WrappedArrow arr a (Product (WrappedArrow arr) b c) Source # |
class Category cat => CocartesianCategory (cat :: k -> k -> Type) where Source #
Cocartesian category is a monoidal category where monoidal product is the categorical coproduct.
inl :: cat a (Coproduct cat a b) Source #
inr :: cat b (Coproduct cat a b) Source #
fanin :: cat a c -> cat b c -> cat (Coproduct cat a b) c Source #
is written as \([f, g]\) in category theory literature.fanin
f g
Instances
class (CartesianCategory cat, CocartesianCategory cat) => BicartesianCategory cat where Source #
Bicartesian category is category which is both cartesian and cocartesian.
We also require distributive morpism.
distr :: cat (Product cat (Coproduct cat a b) c) (Coproduct cat (Product cat a c) (Product cat b c)) Source #
Instances
Monad m => BicartesianCategory (Kleisli m :: Type -> Type -> Type) Source # | |
BicartesianCategory ((->) :: Type -> Type -> Type) Source # | |
Monad m => BicartesianCategory (Star m :: Type -> Type -> Type) Source # | |
ArrowChoice arr => BicartesianCategory (WrappedArrow arr :: Type -> Type -> Type) Source # | |
Defined in Overloaded.Categories distr :: forall (a :: k) (b :: k) (c :: k). WrappedArrow arr (Product (WrappedArrow arr) (Coproduct (WrappedArrow arr) a b) c) (Coproduct (WrappedArrow arr) (Product (WrappedArrow arr) a c) (Product (WrappedArrow arr) b c)) Source # |
class CartesianCategory cat => CCC (cat :: k -> k -> Type) where Source #
Closed cartesian category.
type Exponential cat :: k -> k -> k Source #
represents \(B^A\). This is due how (->) works.Exponential
cat a b
eval :: cat (Product cat (Exponential cat a b) a) b Source #
transpose :: cat (Product cat a b) c -> cat a (Exponential cat b c) Source #
Instances
Monad m => CCC (Kleisli m :: Type -> Type -> Type) Source # | |
Defined in Overloaded.Categories type Exponential (Kleisli m) :: k -> k -> k Source # | |
CCC ((->) :: Type -> Type -> Type) Source # | |
Defined in Overloaded.Categories type Exponential (->) :: k -> k -> k Source # eval :: forall (a :: k) (b :: k). Product (->) (Exponential (->) a b) a -> b Source # transpose :: forall (a :: k) (b :: k) (c :: k). (Product (->) a b -> c) -> a -> Exponential (->) b c Source # | |
Monad m => CCC (Star m :: Type -> Type -> Type) Source # | |
Defined in Overloaded.Categories type Exponential (Star m) :: k -> k -> k Source # | |
ArrowApply arr => CCC (WrappedArrow arr :: Type -> Type -> Type) Source # | |
Defined in Overloaded.Categories type Exponential (WrappedArrow arr) :: k -> k -> k Source # eval :: forall (a :: k) (b :: k). WrappedArrow arr (Product (WrappedArrow arr) (Exponential (WrappedArrow arr) a b) a) b Source # transpose :: forall (a :: k) (b :: k) (c :: k). WrappedArrow arr (Product (WrappedArrow arr) a b) c -> WrappedArrow arr a (Exponential (WrappedArrow arr) b c) Source # |
Overloaded:RecordFields
See GHC.Records.Compat from record-hasfield
package.