{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Text.Sayable
(
Sayable(sayable)
, Saying(Saying, saying)
, t'
, d'
, (&-)
, (&+)
, (&%)
, (&*)
, (&+*)
, (&:*)
, (&?)
, (&+?)
, (&<)
, (&<*)
, (&<?)
, (&!)
, (&!?)
, (&!*)
, (&!$*)
, (&!:*)
, SayableAnn(SayableAnn)
, sez
, sez_
, sayableSubConstraints
, ConstrM
, ofType
, tagVar
, tagSym
, subWrapper
, subElemFilter
, paramVar
, paramSym
, paramNat
, paramTH
)
where
import Control.Applicative ( liftA )
import Control.Monad ( ap )
import qualified Control.Monad.Catch as X
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as BSL
import Data.Either ( rights )
import qualified Data.Int as I
import qualified Data.Map as Map
import Data.Text ( Text, pack )
import qualified Data.Text.Encoding as TE
import qualified Data.Text.Lazy as TL
import qualified Data.Text.Lazy.Encoding as TEL
import qualified Data.Word as W
import GHC.Exts ( Proxy#, proxy# )
import GHC.OverloadedLabels
import GHC.TypeLits ( Symbol, KnownSymbol, symbolVal' )
import Language.Haskell.TH as TH
import Language.Haskell.TH.Datatype
import Numeric.Natural ( Natural )
import Prettyprinter ( (<+>) )
import qualified Prettyprinter as PP
import qualified Prettyprinter.Render.String as PPS
class Sayable (tag :: Symbol) v where
sayable :: v -> Saying tag
default sayable :: PP.Pretty v => v -> Saying tag
sayable = Doc SayableAnn -> Saying tag
forall (tag :: Symbol). Doc SayableAnn -> Saying tag
Saying (Doc SayableAnn -> Saying tag)
-> (v -> Doc SayableAnn) -> v -> Saying tag
forall b c a. (b -> c) -> (a -> b) -> a -> c
. v -> Doc SayableAnn
forall ann. v -> Doc ann
forall a ann. Pretty a => a -> Doc ann
PP.pretty
newtype Saying (tag :: Symbol) = Saying { forall (tag :: Symbol). Saying tag -> Doc SayableAnn
saying :: PP.Doc SayableAnn }
instance Semigroup (Saying tag) where
Saying Doc SayableAnn
sm1 <> :: Saying tag -> Saying tag -> Saying tag
<> Saying Doc SayableAnn
sm2 = Doc SayableAnn -> Saying tag
forall (tag :: Symbol). Doc SayableAnn -> Saying tag
Saying (Doc SayableAnn -> Saying tag) -> Doc SayableAnn -> Saying tag
forall a b. (a -> b) -> a -> b
$ Doc SayableAnn
sm1 Doc SayableAnn -> Doc SayableAnn -> Doc SayableAnn
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Doc SayableAnn
sm2
instance {-# OVERLAPPING #-} (tagA ~ tagB) => Sayable tagA (Saying tagB) where sayable :: Saying tagB -> Saying tagA
sayable = Saying tagB -> Saying tagA
Saying tagB -> Saying tagB
forall a. a -> a
id
instance Sayable tag Text
instance Sayable tag String
instance Sayable tag Char
instance Sayable tag Bool
instance Sayable tag Int
instance Sayable tag Integer
instance Sayable tag I.Int32
instance Sayable tag I.Int64
instance Sayable tag W.Word8
instance Sayable tag W.Word16
instance Sayable tag W.Word32
instance Sayable tag W.Word64
instance Sayable tag Natural
instance Sayable tag Float
instance Sayable tag Double
instance Sayable tag TL.Text
instance Sayable tag BS.ByteString where sayable :: ByteString -> Saying tag
sayable = Text -> Saying tag
forall (tag :: Symbol) v. Sayable tag v => v -> Saying tag
sayable (Text -> Saying tag)
-> (ByteString -> Text) -> ByteString -> Saying tag
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Text
TE.decodeUtf8
instance Sayable tag BSL.ByteString where sayable :: ByteString -> Saying tag
sayable = Text -> Saying tag
forall (tag :: Symbol) v. Sayable tag v => v -> Saying tag
sayable (Text -> Saying tag)
-> (ByteString -> Text) -> ByteString -> Saying tag
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Text
TEL.decodeUtf8
instance Sayable tag X.SomeException where sayable :: SomeException -> Saying tag
sayable = String -> Saying tag
forall (tag :: Symbol) v. Sayable tag v => v -> Saying tag
sayable (String -> Saying tag)
-> (SomeException -> String) -> SomeException -> Saying tag
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SomeException -> String
forall e. Exception e => e -> String
X.displayException
instance Sayable tag (PP.Doc SayableAnn) where sayable :: Doc SayableAnn -> Saying tag
sayable = Doc SayableAnn -> Saying tag
forall (tag :: Symbol). Doc SayableAnn -> Saying tag
Saying
instance {-# OVERLAPPABLE #-} Sayable tag (PP.Doc ann) where sayable :: Doc ann -> Saying tag
sayable = Doc SayableAnn -> Saying tag
forall (tag :: Symbol). Doc SayableAnn -> Saying tag
Saying (Doc SayableAnn -> Saying tag)
-> (Doc ann -> Doc SayableAnn) -> Doc ann -> Saying tag
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Doc ann -> Doc SayableAnn
forall ann xxx. Doc ann -> Doc xxx
PP.unAnnotate
instance PP.Pretty (Saying tag) where pretty :: forall ann. Saying tag -> Doc ann
pretty = Doc SayableAnn -> Doc ann
forall ann xxx. Doc ann -> Doc xxx
PP.unAnnotate (Doc SayableAnn -> Doc ann)
-> (Saying tag -> Doc SayableAnn) -> Saying tag -> Doc ann
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Saying tag -> Doc SayableAnn
forall (tag :: Symbol). Saying tag -> Doc SayableAnn
saying
(&-) :: forall saytag m n . (Sayable saytag m, Sayable saytag n)
=> m -> n -> Saying saytag
m
m &- :: forall (saytag :: Symbol) m n.
(Sayable saytag m, Sayable saytag n) =>
m -> n -> Saying saytag
&- n
n = m -> Saying saytag
forall (tag :: Symbol) v. Sayable tag v => v -> Saying tag
sayable m
m Saying saytag -> Saying saytag -> Saying saytag
forall a. Semigroup a => a -> a -> a
<> n -> Saying saytag
forall (tag :: Symbol) v. Sayable tag v => v -> Saying tag
sayable n
n
infixl 1 &-
(&+) :: forall saytag m n . (Sayable saytag m, Sayable saytag n)
=> m -> n -> Saying saytag
m
m &+ :: forall (saytag :: Symbol) m n.
(Sayable saytag m, Sayable saytag n) =>
m -> n -> Saying saytag
&+ n
n = Doc SayableAnn -> Saying saytag
forall (tag :: Symbol). Doc SayableAnn -> Saying tag
Saying (Doc SayableAnn -> Saying saytag)
-> Doc SayableAnn -> Saying saytag
forall a b. (a -> b) -> a -> b
$ (Saying saytag -> Doc SayableAnn
forall (tag :: Symbol). Saying tag -> Doc SayableAnn
saying (Saying saytag -> Doc SayableAnn)
-> Saying saytag -> Doc SayableAnn
forall a b. (a -> b) -> a -> b
$ forall (tag :: Symbol) v. Sayable tag v => v -> Saying tag
sayable @saytag m
m) Doc SayableAnn -> Doc SayableAnn -> Doc SayableAnn
forall a. Semigroup a => a -> a -> a
<> (Saying saytag -> Doc SayableAnn
forall (tag :: Symbol). Saying tag -> Doc SayableAnn
saying (Saying saytag -> Doc SayableAnn)
-> Saying saytag -> Doc SayableAnn
forall a b. (a -> b) -> a -> b
$ forall (tag :: Symbol) v. Sayable tag v => v -> Saying tag
sayable @saytag n
n)
infixl 1 &+
(&%) :: (Sayable tag m, PP.Pretty n) => m -> n -> Saying tag
m
m &% :: forall (tag :: Symbol) m n.
(Sayable tag m, Pretty n) =>
m -> n -> Saying tag
&% n
n = m -> Saying tag
forall (tag :: Symbol) v. Sayable tag v => v -> Saying tag
sayable m
m Saying tag -> Saying tag -> Saying tag
forall a. Semigroup a => a -> a -> a
<> Doc SayableAnn -> Saying tag
forall (tag :: Symbol) v. Sayable tag v => v -> Saying tag
sayable (n -> Doc SayableAnn
forall ann. n -> Doc ann
forall a ann. Pretty a => a -> Doc ann
PP.pretty n
n :: PP.Doc SayableAnn)
infixl 1 &%
(&!) :: forall tag m . Sayable tag m
=> (PP.Doc SayableAnn -> PP.Doc SayableAnn) -> m -> Saying tag
Doc SayableAnn -> Doc SayableAnn
pf &! :: forall (tag :: Symbol) m.
Sayable tag m =>
(Doc SayableAnn -> Doc SayableAnn) -> m -> Saying tag
&! m
m = Doc SayableAnn -> Saying tag
forall (tag :: Symbol). Doc SayableAnn -> Saying tag
Saying (Doc SayableAnn -> Saying tag) -> Doc SayableAnn -> Saying tag
forall a b. (a -> b) -> a -> b
$ Doc SayableAnn -> Doc SayableAnn
pf (Doc SayableAnn -> Doc SayableAnn)
-> Doc SayableAnn -> Doc SayableAnn
forall a b. (a -> b) -> a -> b
$ Saying tag -> Doc SayableAnn
forall (tag :: Symbol). Saying tag -> Doc SayableAnn
saying (Saying tag -> Doc SayableAnn) -> Saying tag -> Doc SayableAnn
forall a b. (a -> b) -> a -> b
$ forall (tag :: Symbol) v. Sayable tag v => v -> Saying tag
sayable @tag m
m
infixl 2 &!
(&*) :: forall tag m e t
. (Sayable tag m, Sayable tag e, Foldable t) => m -> t e -> Saying tag
m
m &* :: forall (tag :: Symbol) m e (t :: * -> *).
(Sayable tag m, Sayable tag e, Foldable t) =>
m -> t e -> Saying tag
&* t e
l = let addElem :: e -> (Doc SayableAnn, Saying tag) -> (Doc SayableAnn, Saying tag)
addElem e
e (Doc SayableAnn
s, Saying Doc SayableAnn
p) =
(Doc SayableAnn
"," Doc SayableAnn -> Doc SayableAnn -> Doc SayableAnn
forall a. Semigroup a => a -> a -> a
<> Doc SayableAnn
forall ann. Doc ann
PP.softline, Doc SayableAnn -> Saying tag
forall (tag :: Symbol). Doc SayableAnn -> Saying tag
Saying (Doc SayableAnn -> Saying tag) -> Doc SayableAnn -> Saying tag
forall a b. (a -> b) -> a -> b
$ Saying tag -> Doc SayableAnn
forall (tag :: Symbol). Saying tag -> Doc SayableAnn
saying (forall (tag :: Symbol) v. Sayable tag v => v -> Saying tag
sayable @tag e
e) Doc SayableAnn -> Doc SayableAnn -> Doc SayableAnn
forall a. Semigroup a => a -> a -> a
<> Doc SayableAnn
s Doc SayableAnn -> Doc SayableAnn -> Doc SayableAnn
forall a. Semigroup a => a -> a -> a
<> Doc SayableAnn
p)
in m -> Saying tag
forall (tag :: Symbol) v. Sayable tag v => v -> Saying tag
sayable m
m Saying tag -> Saying tag -> Saying tag
forall a. Semigroup a => a -> a -> a
<> ((Doc SayableAnn, Saying tag) -> Saying tag
forall a b. (a, b) -> b
snd ((Doc SayableAnn, Saying tag) -> Saying tag)
-> (Doc SayableAnn, Saying tag) -> Saying tag
forall a b. (a -> b) -> a -> b
$ (e -> (Doc SayableAnn, Saying tag) -> (Doc SayableAnn, Saying tag))
-> (Doc SayableAnn, Saying tag)
-> t e
-> (Doc SayableAnn, Saying tag)
forall a b. (a -> b -> b) -> b -> t a -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr e -> (Doc SayableAnn, Saying tag) -> (Doc SayableAnn, Saying tag)
addElem (Doc SayableAnn
"", Doc SayableAnn -> Saying tag
forall (tag :: Symbol). Doc SayableAnn -> Saying tag
Saying Doc SayableAnn
forall ann. Doc ann
PP.emptyDoc) t e
l)
infixl 1 &*
(&+*) :: forall tag m e t
. (Sayable tag m, Sayable tag e, Foldable t) => m -> t e -> Saying tag
m
m &+* :: forall (tag :: Symbol) m e (t :: * -> *).
(Sayable tag m, Sayable tag e, Foldable t) =>
m -> t e -> Saying tag
&+* t e
l = let addElem :: e -> (Doc SayableAnn, Saying Any) -> (Doc SayableAnn, Saying Any)
addElem e
e (Doc SayableAnn
s, Saying Doc SayableAnn
p) =
(Doc SayableAnn
"," Doc SayableAnn -> Doc SayableAnn -> Doc SayableAnn
forall a. Semigroup a => a -> a -> a
<> Doc SayableAnn
forall ann. Doc ann
PP.softline, Doc SayableAnn -> Saying Any
forall (tag :: Symbol). Doc SayableAnn -> Saying tag
Saying (Doc SayableAnn -> Saying Any) -> Doc SayableAnn -> Saying Any
forall a b. (a -> b) -> a -> b
$ Saying tag -> Doc SayableAnn
forall (tag :: Symbol). Saying tag -> Doc SayableAnn
saying (forall (tag :: Symbol) v. Sayable tag v => v -> Saying tag
sayable @tag e
e) Doc SayableAnn -> Doc SayableAnn -> Doc SayableAnn
forall a. Semigroup a => a -> a -> a
<> Doc SayableAnn
s Doc SayableAnn -> Doc SayableAnn -> Doc SayableAnn
forall a. Semigroup a => a -> a -> a
<> Doc SayableAnn
p)
in Doc SayableAnn -> Saying tag
forall (tag :: Symbol). Doc SayableAnn -> Saying tag
Saying (Saying tag -> Doc SayableAnn
forall (tag :: Symbol). Saying tag -> Doc SayableAnn
saying (forall (tag :: Symbol) v. Sayable tag v => v -> Saying tag
sayable @tag m
m)
Doc SayableAnn -> Doc SayableAnn -> Doc SayableAnn
forall a. Semigroup a => a -> a -> a
<> Saying Any -> Doc SayableAnn
forall (tag :: Symbol). Saying tag -> Doc SayableAnn
saying ((Doc SayableAnn, Saying Any) -> Saying Any
forall a b. (a, b) -> b
snd ((Doc SayableAnn, Saying Any) -> Saying Any)
-> (Doc SayableAnn, Saying Any) -> Saying Any
forall a b. (a -> b) -> a -> b
$ (e -> (Doc SayableAnn, Saying Any) -> (Doc SayableAnn, Saying Any))
-> (Doc SayableAnn, Saying Any)
-> t e
-> (Doc SayableAnn, Saying Any)
forall a b. (a -> b -> b) -> b -> t a -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr e -> (Doc SayableAnn, Saying Any) -> (Doc SayableAnn, Saying Any)
addElem (Doc SayableAnn
"", Doc SayableAnn -> Saying Any
forall (tag :: Symbol). Doc SayableAnn -> Saying tag
Saying Doc SayableAnn
forall ann. Doc ann
PP.emptyDoc) t e
l))
infixl 1 &+*
(&:*) :: forall tag m e t
. (Sayable tag m, Sayable tag e, Foldable t) => m -> t e -> Saying tag
m
m &:* :: forall (tag :: Symbol) m e (t :: * -> *).
(Sayable tag m, Sayable tag e, Foldable t) =>
m -> t e -> Saying tag
&:* t e
l = let addElem :: e -> (Maybe m, Saying tag) -> (Maybe m, Saying tag)
addElem e
e (Maybe m
s, Saying Doc SayableAnn
p) = (m -> Maybe m
forall a. a -> Maybe a
Just m
m,
case Maybe m
s of
Maybe m
Nothing -> forall (tag :: Symbol) v. Sayable tag v => v -> Saying tag
sayable @tag e
e Saying tag -> Doc SayableAnn -> Saying tag
forall (saytag :: Symbol) m n.
(Sayable saytag m, Sayable saytag n) =>
m -> n -> Saying saytag
&+ Doc SayableAnn
p
Just m
s' -> forall (tag :: Symbol) v. Sayable tag v => v -> Saying tag
sayable @tag e
e Saying tag -> m -> Saying tag
forall (saytag :: Symbol) m n.
(Sayable saytag m, Sayable saytag n) =>
m -> n -> Saying saytag
&+ m
s' Saying tag -> Doc SayableAnn -> Saying tag
forall (saytag :: Symbol) m n.
(Sayable saytag m, Sayable saytag n) =>
m -> n -> Saying saytag
&+ Doc SayableAnn
p
)
in (Maybe m, Saying tag) -> Saying tag
forall a b. (a, b) -> b
snd ((Maybe m, Saying tag) -> Saying tag)
-> (Maybe m, Saying tag) -> Saying tag
forall a b. (a -> b) -> a -> b
$ (e -> (Maybe m, Saying tag) -> (Maybe m, Saying tag))
-> (Maybe m, Saying tag) -> t e -> (Maybe m, Saying tag)
forall a b. (a -> b -> b) -> b -> t a -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr e -> (Maybe m, Saying tag) -> (Maybe m, Saying tag)
addElem (Maybe m
forall a. Maybe a
Nothing, Doc SayableAnn -> Saying tag
forall (tag :: Symbol). Doc SayableAnn -> Saying tag
Saying Doc SayableAnn
forall ann. Doc ann
PP.emptyDoc) t e
l
infixl 2 &:*
(&!*) :: forall tag m t
. (Sayable tag m, Foldable t)
=> ([PP.Doc SayableAnn] -> PP.Doc SayableAnn) -> t m -> Saying tag
[Doc SayableAnn] -> Doc SayableAnn
pf &!* :: forall (tag :: Symbol) m (t :: * -> *).
(Sayable tag m, Foldable t) =>
([Doc SayableAnn] -> Doc SayableAnn) -> t m -> Saying tag
&!* t m
l = let addElem :: m
-> (Doc SayableAnn, [Doc SayableAnn])
-> (Doc SayableAnn, [Doc SayableAnn])
addElem m
e (Doc SayableAnn
s, [Doc SayableAnn]
p) = (Doc SayableAnn
"," Doc SayableAnn -> Doc SayableAnn -> Doc SayableAnn
forall a. Semigroup a => a -> a -> a
<> Doc SayableAnn
forall ann. Doc ann
PP.softline
, Saying tag -> Doc SayableAnn
forall (tag :: Symbol). Saying tag -> Doc SayableAnn
saying (forall (tag :: Symbol) v. Sayable tag v => v -> Saying tag
sayable @tag m
e) Doc SayableAnn -> Doc SayableAnn -> Doc SayableAnn
forall a. Semigroup a => a -> a -> a
<> Doc SayableAnn
s Doc SayableAnn -> [Doc SayableAnn] -> [Doc SayableAnn]
forall a. a -> [a] -> [a]
: [Doc SayableAnn]
p)
in Doc SayableAnn -> Saying tag
forall (tag :: Symbol). Doc SayableAnn -> Saying tag
Saying (Doc SayableAnn -> Saying tag) -> Doc SayableAnn -> Saying tag
forall a b. (a -> b) -> a -> b
$ [Doc SayableAnn] -> Doc SayableAnn
pf ([Doc SayableAnn] -> Doc SayableAnn)
-> [Doc SayableAnn] -> Doc SayableAnn
forall a b. (a -> b) -> a -> b
$ (Doc SayableAnn, [Doc SayableAnn]) -> [Doc SayableAnn]
forall a b. (a, b) -> b
snd ((Doc SayableAnn, [Doc SayableAnn]) -> [Doc SayableAnn])
-> (Doc SayableAnn, [Doc SayableAnn]) -> [Doc SayableAnn]
forall a b. (a -> b) -> a -> b
$ (m
-> (Doc SayableAnn, [Doc SayableAnn])
-> (Doc SayableAnn, [Doc SayableAnn]))
-> (Doc SayableAnn, [Doc SayableAnn])
-> t m
-> (Doc SayableAnn, [Doc SayableAnn])
forall a b. (a -> b -> b) -> b -> t a -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr m
-> (Doc SayableAnn, [Doc SayableAnn])
-> (Doc SayableAnn, [Doc SayableAnn])
addElem (Doc SayableAnn
"", []) t m
l
infixl 2 &!*
(&!$*) :: forall tag m t
. (Sayable tag m, Foldable t)
=> (PP.Doc SayableAnn -> PP.Doc SayableAnn) -> t m -> Saying tag
Doc SayableAnn -> Doc SayableAnn
pf &!$* :: forall (tag :: Symbol) m (t :: * -> *).
(Sayable tag m, Foldable t) =>
(Doc SayableAnn -> Doc SayableAnn) -> t m -> Saying tag
&!$* t m
l = let addElem :: m
-> (Doc SayableAnn, Doc SayableAnn)
-> (Doc SayableAnn, Doc SayableAnn)
addElem m
e (Doc SayableAnn
s, Doc SayableAnn
p) = (Doc SayableAnn
"," Doc SayableAnn -> Doc SayableAnn -> Doc SayableAnn
forall a. Semigroup a => a -> a -> a
<> Doc SayableAnn
forall ann. Doc ann
PP.softline
, Saying tag -> Doc SayableAnn
forall (tag :: Symbol). Saying tag -> Doc SayableAnn
saying (forall (tag :: Symbol) v. Sayable tag v => v -> Saying tag
sayable @tag m
e) Doc SayableAnn -> Doc SayableAnn -> Doc SayableAnn
forall a. Semigroup a => a -> a -> a
<> Doc SayableAnn
s Doc SayableAnn -> Doc SayableAnn -> Doc SayableAnn
forall a. Semigroup a => a -> a -> a
<> Doc SayableAnn
p)
in Doc SayableAnn -> Saying tag
forall (tag :: Symbol). Doc SayableAnn -> Saying tag
Saying (Doc SayableAnn -> Saying tag) -> Doc SayableAnn -> Saying tag
forall a b. (a -> b) -> a -> b
$ Doc SayableAnn -> Doc SayableAnn
pf (Doc SayableAnn -> Doc SayableAnn)
-> Doc SayableAnn -> Doc SayableAnn
forall a b. (a -> b) -> a -> b
$ (Doc SayableAnn, Doc SayableAnn) -> Doc SayableAnn
forall a b. (a, b) -> b
snd ((Doc SayableAnn, Doc SayableAnn) -> Doc SayableAnn)
-> (Doc SayableAnn, Doc SayableAnn) -> Doc SayableAnn
forall a b. (a -> b) -> a -> b
$ (m
-> (Doc SayableAnn, Doc SayableAnn)
-> (Doc SayableAnn, Doc SayableAnn))
-> (Doc SayableAnn, Doc SayableAnn)
-> t m
-> (Doc SayableAnn, Doc SayableAnn)
forall a b. (a -> b -> b) -> b -> t a -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr m
-> (Doc SayableAnn, Doc SayableAnn)
-> (Doc SayableAnn, Doc SayableAnn)
addElem (Doc SayableAnn
"", Doc SayableAnn
forall a. Monoid a => a
mempty) t m
l
infixl 2 &!$*
(&!:*) :: forall tag m t b . (Sayable tag b, Sayable tag m, Foldable t)
=> ([PP.Doc SayableAnn] -> PP.Doc SayableAnn) -> b -> t m -> Saying tag
[Doc SayableAnn] -> Doc SayableAnn
pf &!:* :: forall (tag :: Symbol) m (t :: * -> *) b.
(Sayable tag b, Sayable tag m, Foldable t) =>
([Doc SayableAnn] -> Doc SayableAnn) -> b -> t m -> Saying tag
&!:* b
b = let addElem :: m -> (Maybe b, [Doc SayableAnn]) -> (Maybe b, [Doc SayableAnn])
addElem m
e (Maybe b
s, [Doc SayableAnn]
p) =
(b -> Maybe b
forall a. a -> Maybe a
Just b
b, (case Maybe b
s of
Maybe b
Nothing -> Saying tag -> Doc SayableAnn
forall (tag :: Symbol). Saying tag -> Doc SayableAnn
saying (forall (tag :: Symbol) v. Sayable tag v => v -> Saying tag
sayable @tag m
e)
Just b
x -> Saying tag -> Doc SayableAnn
forall (tag :: Symbol). Saying tag -> Doc SayableAnn
saying (forall (tag :: Symbol) v. Sayable tag v => v -> Saying tag
sayable @tag m
e Saying tag -> b -> Saying tag
forall (saytag :: Symbol) m n.
(Sayable saytag m, Sayable saytag n) =>
m -> n -> Saying saytag
&+ b
x)
) Doc SayableAnn -> [Doc SayableAnn] -> [Doc SayableAnn]
forall a. a -> [a] -> [a]
: [Doc SayableAnn]
p)
in Doc SayableAnn -> Saying tag
forall (tag :: Symbol). Doc SayableAnn -> Saying tag
Saying (Doc SayableAnn -> Saying tag)
-> (t m -> Doc SayableAnn) -> t m -> Saying tag
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Doc SayableAnn] -> Doc SayableAnn
pf ([Doc SayableAnn] -> Doc SayableAnn)
-> (t m -> [Doc SayableAnn]) -> t m -> Doc SayableAnn
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Maybe b, [Doc SayableAnn]) -> [Doc SayableAnn]
forall a b. (a, b) -> b
snd ((Maybe b, [Doc SayableAnn]) -> [Doc SayableAnn])
-> (t m -> (Maybe b, [Doc SayableAnn])) -> t m -> [Doc SayableAnn]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (m -> (Maybe b, [Doc SayableAnn]) -> (Maybe b, [Doc SayableAnn]))
-> (Maybe b, [Doc SayableAnn])
-> t m
-> (Maybe b, [Doc SayableAnn])
forall a b. (a -> b -> b) -> b -> t a -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr m -> (Maybe b, [Doc SayableAnn]) -> (Maybe b, [Doc SayableAnn])
addElem (Maybe b
forall a. Maybe a
Nothing, [])
infixl 2 &!:*
(&?) :: forall tag m e
. (Sayable tag m, Sayable tag e) => m -> Maybe e -> Saying tag
m
m &? :: forall (tag :: Symbol) m e.
(Sayable tag m, Sayable tag e) =>
m -> Maybe e -> Saying tag
&? Maybe e
Nothing = m -> Saying tag
forall (tag :: Symbol) v. Sayable tag v => v -> Saying tag
sayable m
m
m
m &? (Just e
a) = m -> Saying tag
forall (tag :: Symbol) v. Sayable tag v => v -> Saying tag
sayable m
m Saying tag -> Saying tag -> Saying tag
forall a. Semigroup a => a -> a -> a
<> e -> Saying tag
forall (tag :: Symbol) v. Sayable tag v => v -> Saying tag
sayable e
a
infixl 1 &?
(&!?) :: forall tag e . (Sayable tag e)
=> (PP.Doc SayableAnn -> PP.Doc SayableAnn) -> Maybe e -> Saying tag
Doc SayableAnn -> Doc SayableAnn
_ &!? :: forall (tag :: Symbol) e.
Sayable tag e =>
(Doc SayableAnn -> Doc SayableAnn) -> Maybe e -> Saying tag
&!? Maybe e
Nothing = Doc SayableAnn -> Saying tag
forall (tag :: Symbol). Doc SayableAnn -> Saying tag
Saying Doc SayableAnn
forall a. Monoid a => a
mempty
Doc SayableAnn -> Doc SayableAnn
pf &!? (Just e
a) = Doc SayableAnn -> Saying tag
forall (tag :: Symbol). Doc SayableAnn -> Saying tag
Saying (Doc SayableAnn -> Saying tag) -> Doc SayableAnn -> Saying tag
forall a b. (a -> b) -> a -> b
$ Doc SayableAnn -> Doc SayableAnn
pf (Doc SayableAnn -> Doc SayableAnn)
-> Doc SayableAnn -> Doc SayableAnn
forall a b. (a -> b) -> a -> b
$ Saying tag -> Doc SayableAnn
forall (tag :: Symbol). Saying tag -> Doc SayableAnn
saying (Saying tag -> Doc SayableAnn) -> Saying tag -> Doc SayableAnn
forall a b. (a -> b) -> a -> b
$ forall (tag :: Symbol) v. Sayable tag v => v -> Saying tag
sayable @tag e
a
infixl 1 &!?
(&<) :: forall saytag m n . (Sayable saytag m, Sayable saytag n)
=> m -> n -> Saying saytag
m
m &< :: forall (saytag :: Symbol) m n.
(Sayable saytag m, Sayable saytag n) =>
m -> n -> Saying saytag
&< n
n = Doc SayableAnn -> Saying saytag
forall (tag :: Symbol). Doc SayableAnn -> Saying tag
Saying
(Doc SayableAnn -> Saying saytag)
-> Doc SayableAnn -> Saying saytag
forall a b. (a -> b) -> a -> b
$ (Saying saytag -> Doc SayableAnn
forall (tag :: Symbol). Saying tag -> Doc SayableAnn
saying (Saying saytag -> Doc SayableAnn)
-> Saying saytag -> Doc SayableAnn
forall a b. (a -> b) -> a -> b
$ forall (tag :: Symbol) v. Sayable tag v => v -> Saying tag
sayable @saytag m
m)
Doc SayableAnn -> Doc SayableAnn -> Doc SayableAnn
forall a. Semigroup a => a -> a -> a
<> (Doc SayableAnn
forall ann. Doc ann
PP.line :: PP.Doc SayableAnn)
Doc SayableAnn -> Doc SayableAnn -> Doc SayableAnn
forall a. Semigroup a => a -> a -> a
<> (Saying saytag -> Doc SayableAnn
forall (tag :: Symbol). Saying tag -> Doc SayableAnn
saying (Saying saytag -> Doc SayableAnn)
-> Saying saytag -> Doc SayableAnn
forall a b. (a -> b) -> a -> b
$ forall (tag :: Symbol) v. Sayable tag v => v -> Saying tag
sayable @saytag n
n)
infixl 1 &<
(&<*) :: forall saytag m n t . (Sayable saytag m, Sayable saytag n, Foldable t)
=> m -> t n -> Saying saytag
m
m &<* :: forall (tag :: Symbol) m e (t :: * -> *).
(Sayable tag m, Sayable tag e, Foldable t) =>
m -> t e -> Saying tag
&<* t n
n = let addElem :: n
-> (Doc SayableAnn, Saying saytag)
-> (Doc SayableAnn, Saying saytag)
addElem n
e (Doc SayableAnn
s, Saying Doc SayableAnn
p) =
(Doc SayableAnn
", ", Doc SayableAnn -> Saying saytag
forall (tag :: Symbol). Doc SayableAnn -> Saying tag
Saying (Doc SayableAnn -> Saying saytag)
-> Doc SayableAnn -> Saying saytag
forall a b. (a -> b) -> a -> b
$ Saying saytag -> Doc SayableAnn
forall (tag :: Symbol). Saying tag -> Doc SayableAnn
saying (forall (tag :: Symbol) v. Sayable tag v => v -> Saying tag
sayable @saytag n
e) Doc SayableAnn -> Doc SayableAnn -> Doc SayableAnn
forall a. Semigroup a => a -> a -> a
<> Doc SayableAnn
s Doc SayableAnn -> Doc SayableAnn -> Doc SayableAnn
forall a. Semigroup a => a -> a -> a
<> Doc SayableAnn
p)
in Doc SayableAnn -> Saying saytag
forall (tag :: Symbol). Doc SayableAnn -> Saying tag
Saying
(Doc SayableAnn -> Saying saytag)
-> Doc SayableAnn -> Saying saytag
forall a b. (a -> b) -> a -> b
$ (Saying saytag -> Doc SayableAnn
forall (tag :: Symbol). Saying tag -> Doc SayableAnn
saying (Saying saytag -> Doc SayableAnn)
-> Saying saytag -> Doc SayableAnn
forall a b. (a -> b) -> a -> b
$ forall (tag :: Symbol) v. Sayable tag v => v -> Saying tag
sayable @saytag m
m)
Doc SayableAnn -> Doc SayableAnn -> Doc SayableAnn
forall a. Semigroup a => a -> a -> a
<> (Doc SayableAnn
forall ann. Doc ann
PP.line :: PP.Doc SayableAnn)
Doc SayableAnn -> Doc SayableAnn -> Doc SayableAnn
forall a. Semigroup a => a -> a -> a
<> (Saying saytag -> Doc SayableAnn
forall (tag :: Symbol). Saying tag -> Doc SayableAnn
saying (Saying saytag -> Doc SayableAnn)
-> Saying saytag -> Doc SayableAnn
forall a b. (a -> b) -> a -> b
$ forall (tag :: Symbol) v. Sayable tag v => v -> Saying tag
sayable @saytag
((Doc SayableAnn, Saying saytag) -> Saying saytag
forall a b. (a, b) -> b
snd ((Doc SayableAnn, Saying saytag) -> Saying saytag)
-> (Doc SayableAnn, Saying saytag) -> Saying saytag
forall a b. (a -> b) -> a -> b
$ (n
-> (Doc SayableAnn, Saying saytag)
-> (Doc SayableAnn, Saying saytag))
-> (Doc SayableAnn, Saying saytag)
-> t n
-> (Doc SayableAnn, Saying saytag)
forall a b. (a -> b -> b) -> b -> t a -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr n
-> (Doc SayableAnn, Saying saytag)
-> (Doc SayableAnn, Saying saytag)
addElem (Doc SayableAnn
"", Doc SayableAnn -> Saying saytag
forall (tag :: Symbol). Doc SayableAnn -> Saying tag
Saying Doc SayableAnn
forall ann. Doc ann
PP.emptyDoc) t n
n))
infixl 1 &<*
(&<?) :: forall saytag m n . (Sayable saytag m, Sayable saytag n)
=> m -> Maybe n -> Saying saytag
m
m &<? :: forall (tag :: Symbol) m e.
(Sayable tag m, Sayable tag e) =>
m -> Maybe e -> Saying tag
&<? Maybe n
Nothing = m -> Saying saytag
forall (tag :: Symbol) v. Sayable tag v => v -> Saying tag
sayable m
m
m
m &<? (Just n
n) = Doc SayableAnn -> Saying saytag
forall (tag :: Symbol). Doc SayableAnn -> Saying tag
Saying
(Doc SayableAnn -> Saying saytag)
-> Doc SayableAnn -> Saying saytag
forall a b. (a -> b) -> a -> b
$ (Saying saytag -> Doc SayableAnn
forall (tag :: Symbol). Saying tag -> Doc SayableAnn
saying (Saying saytag -> Doc SayableAnn)
-> Saying saytag -> Doc SayableAnn
forall a b. (a -> b) -> a -> b
$ forall (tag :: Symbol) v. Sayable tag v => v -> Saying tag
sayable @saytag m
m)
Doc SayableAnn -> Doc SayableAnn -> Doc SayableAnn
forall a. Semigroup a => a -> a -> a
<> (Doc SayableAnn
forall ann. Doc ann
PP.line :: PP.Doc SayableAnn)
Doc SayableAnn -> Doc SayableAnn -> Doc SayableAnn
forall a. Semigroup a => a -> a -> a
<> (Saying saytag -> Doc SayableAnn
forall (tag :: Symbol). Saying tag -> Doc SayableAnn
saying (Saying saytag -> Doc SayableAnn)
-> Saying saytag -> Doc SayableAnn
forall a b. (a -> b) -> a -> b
$ forall (tag :: Symbol) v. Sayable tag v => v -> Saying tag
sayable @saytag n
n)
infixl 1 &<?
(&+?) :: forall saytag m n . (Sayable saytag m, Sayable saytag n)
=> m -> Maybe n -> Saying saytag
m
m &+? :: forall (tag :: Symbol) m e.
(Sayable tag m, Sayable tag e) =>
m -> Maybe e -> Saying tag
&+? Maybe n
Nothing = m -> Saying saytag
forall (tag :: Symbol) v. Sayable tag v => v -> Saying tag
sayable m
m
m
m &+? (Just n
n) = Doc SayableAnn -> Saying saytag
forall (tag :: Symbol). Doc SayableAnn -> Saying tag
Saying
(Doc SayableAnn -> Saying saytag)
-> Doc SayableAnn -> Saying saytag
forall a b. (a -> b) -> a -> b
$ (Saying saytag -> Doc SayableAnn
forall (tag :: Symbol). Saying tag -> Doc SayableAnn
saying (Saying saytag -> Doc SayableAnn)
-> Saying saytag -> Doc SayableAnn
forall a b. (a -> b) -> a -> b
$ forall (tag :: Symbol) v. Sayable tag v => v -> Saying tag
sayable @saytag m
m)
Doc SayableAnn -> Doc SayableAnn -> Doc SayableAnn
forall a. Semigroup a => a -> a -> a
<> (Saying saytag -> Doc SayableAnn
forall (tag :: Symbol). Saying tag -> Doc SayableAnn
saying (Saying saytag -> Doc SayableAnn)
-> Saying saytag -> Doc SayableAnn
forall a b. (a -> b) -> a -> b
$ forall (tag :: Symbol) v. Sayable tag v => v -> Saying tag
sayable @saytag n
n)
infixl 1 &+?
t' :: Text -> Text
t' :: Text -> Text
t' = Text -> Text
forall a. a -> a
id
{-# INLINE t' #-}
d' :: PP.Pretty n => n -> PP.Doc SayableAnn
d' :: forall n. Pretty n => n -> Doc SayableAnn
d' = n -> Doc SayableAnn
forall ann. n -> Doc ann
forall a ann. Pretty a => a -> Doc ann
PP.pretty
data SayableAnn = SayableAnn Text
instance KnownSymbol ann => IsLabel (ann :: Symbol) SayableAnn where
fromLabel :: SayableAnn
fromLabel = Text -> SayableAnn
SayableAnn (Text -> SayableAnn) -> Text -> SayableAnn
forall a b. (a -> b) -> a -> b
$ String -> Text
pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ Proxy# ann -> String
forall (n :: Symbol). KnownSymbol n => Proxy# n -> String
symbolVal' (Proxy# ann
forall {k} (a :: k). Proxy# a
proxy# :: Proxy# ann)
sez :: forall saytag a . Sayable saytag a => a -> String
sez :: forall (saytag :: Symbol) a. Sayable saytag a => a -> String
sez = Doc SayableAnn -> String
forall a. Show a => a -> String
show (Doc SayableAnn -> String) -> (a -> Doc SayableAnn) -> a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Saying saytag -> Doc SayableAnn
forall (tag :: Symbol). Saying tag -> Doc SayableAnn
saying (Saying saytag -> Doc SayableAnn)
-> (a -> Saying saytag) -> a -> Doc SayableAnn
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (tag :: Symbol) v. Sayable tag v => v -> Saying tag
sayable @saytag
sez_ :: forall saytag a . Sayable saytag a => a -> String
sez_ :: forall (saytag :: Symbol) a. Sayable saytag a => a -> String
sez_ = SimpleDocStream SayableAnn -> String
forall ann. SimpleDocStream ann -> String
PPS.renderString
(SimpleDocStream SayableAnn -> String)
-> (a -> SimpleDocStream SayableAnn) -> a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LayoutOptions -> Doc SayableAnn -> SimpleDocStream SayableAnn
forall ann. LayoutOptions -> Doc ann -> SimpleDocStream ann
PP.layoutPretty (PageWidth -> LayoutOptions
PP.LayoutOptions PageWidth
PP.Unbounded)
(Doc SayableAnn -> SimpleDocStream SayableAnn)
-> (a -> Doc SayableAnn) -> a -> SimpleDocStream SayableAnn
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Saying saytag -> Doc SayableAnn
forall (tag :: Symbol). Saying tag -> Doc SayableAnn
saying (Saying saytag -> Doc SayableAnn)
-> (a -> Saying saytag) -> a -> Doc SayableAnn
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (tag :: Symbol) v. Sayable tag v => v -> Saying tag
sayable @saytag
sayableSubConstraints :: ConstrM () -> PredQ
sayableSubConstraints :: ConstrM () -> PredQ
sayableSubConstraints ConstrM ()
cspec =
let initCtx :: SCCtx
initCtx = SCCtx { cTgt :: Name
cTgt = ''()
, cFilt :: Name -> Bool
cFilt = Bool -> Name -> Bool
forall a b. a -> b -> a
const Bool
True
, cSaytag :: Either Type String
cSaytag = String -> Either Type String
forall a b. b -> Either a b
Right String
"saytag"
, cVars :: [Either Type String]
cVars = [Either Type String]
forall a. Monoid a => a
mempty
, cWrapper :: Maybe Type
cWrapper = Maybe Type
forall a. Maybe a
Nothing
}
(SCCtx
ctx, ()
_) = ConstrM () -> SCCtx -> (SCCtx, ())
forall a. ConstrM a -> SCCtx -> (SCCtx, a)
runConstrM ConstrM ()
cspec SCCtx
initCtx
in (Name -> Bool)
-> Name
-> Either Type String
-> Maybe Type
-> [Either Type String]
-> PredQ
sayableSubConstraints' (SCCtx -> Name -> Bool
cFilt SCCtx
ctx) (SCCtx -> Name
cTgt SCCtx
ctx) (SCCtx -> Either Type String
cSaytag SCCtx
ctx) (SCCtx -> Maybe Type
cWrapper SCCtx
ctx) (SCCtx -> [Either Type String]
cVars SCCtx
ctx)
newtype ConstrM a = ConstrM { forall a. ConstrM a -> SCCtx -> (SCCtx, a)
runConstrM :: SCCtx -> (SCCtx, a) }
instance Applicative ConstrM where
pure :: forall a. a -> ConstrM a
pure a
x = (SCCtx -> (SCCtx, a)) -> ConstrM a
forall a. (SCCtx -> (SCCtx, a)) -> ConstrM a
ConstrM ((SCCtx -> (SCCtx, a)) -> ConstrM a)
-> (SCCtx -> (SCCtx, a)) -> ConstrM a
forall a b. (a -> b) -> a -> b
$ \SCCtx
c -> (SCCtx
c, a
x)
<*> :: forall a b. ConstrM (a -> b) -> ConstrM a -> ConstrM b
(<*>) = ConstrM (a -> b) -> ConstrM a -> ConstrM b
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
ap
instance Functor ConstrM where fmap :: forall a b. (a -> b) -> ConstrM a -> ConstrM b
fmap = (a -> b) -> ConstrM a -> ConstrM b
forall (f :: * -> *) a b. Applicative f => (a -> b) -> f a -> f b
liftA
instance Monad ConstrM where
return :: forall a. a -> ConstrM a
return = a -> ConstrM a
forall a. a -> ConstrM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
ConstrM a
m >>= :: forall a b. ConstrM a -> (a -> ConstrM b) -> ConstrM b
>>= a -> ConstrM b
k = (SCCtx -> (SCCtx, b)) -> ConstrM b
forall a. (SCCtx -> (SCCtx, a)) -> ConstrM a
ConstrM ((SCCtx -> (SCCtx, b)) -> ConstrM b)
-> (SCCtx -> (SCCtx, b)) -> ConstrM b
forall a b. (a -> b) -> a -> b
$ \SCCtx
c -> let (SCCtx
c', a
a) = ConstrM a -> SCCtx -> (SCCtx, a)
forall a. ConstrM a -> SCCtx -> (SCCtx, a)
runConstrM ConstrM a
m SCCtx
c in ConstrM b -> SCCtx -> (SCCtx, b)
forall a. ConstrM a -> SCCtx -> (SCCtx, a)
runConstrM (a -> ConstrM b
k a
a) SCCtx
c'
ofType :: Name -> ConstrM ()
ofType :: Name -> ConstrM ()
ofType Name
nm = (SCCtx -> (SCCtx, ())) -> ConstrM ()
forall a. (SCCtx -> (SCCtx, a)) -> ConstrM a
ConstrM ((SCCtx -> (SCCtx, ())) -> ConstrM ())
-> (SCCtx -> (SCCtx, ())) -> ConstrM ()
forall a b. (a -> b) -> a -> b
$ \SCCtx
c -> (SCCtx
c { cTgt = nm }, ())
tagVar :: String -> ConstrM ()
tagVar :: String -> ConstrM ()
tagVar String
var = (SCCtx -> (SCCtx, ())) -> ConstrM ()
forall a. (SCCtx -> (SCCtx, a)) -> ConstrM a
ConstrM ((SCCtx -> (SCCtx, ())) -> ConstrM ())
-> (SCCtx -> (SCCtx, ())) -> ConstrM ()
forall a b. (a -> b) -> a -> b
$ \SCCtx
c -> (SCCtx
c { cSaytag = Right var }, ())
tagSym :: String -> ConstrM ()
tagSym :: String -> ConstrM ()
tagSym String
str = (SCCtx -> (SCCtx, ())) -> ConstrM ()
forall a. (SCCtx -> (SCCtx, a)) -> ConstrM a
ConstrM ((SCCtx -> (SCCtx, ())) -> ConstrM ())
-> (SCCtx -> (SCCtx, ())) -> ConstrM ()
forall a b. (a -> b) -> a -> b
$ \SCCtx
c -> (SCCtx
c { cSaytag = Left $ TH.LitT $ TH.StrTyLit str }, ())
subWrapper :: Type -> ConstrM ()
subWrapper :: Type -> ConstrM ()
subWrapper Type
wrp = (SCCtx -> (SCCtx, ())) -> ConstrM ()
forall a. (SCCtx -> (SCCtx, a)) -> ConstrM a
ConstrM ((SCCtx -> (SCCtx, ())) -> ConstrM ())
-> (SCCtx -> (SCCtx, ())) -> ConstrM ()
forall a b. (a -> b) -> a -> b
$ \SCCtx
c -> (SCCtx
c { cWrapper = Just wrp }, ())
subElemFilter :: (Name -> Bool) -> ConstrM ()
subElemFilter :: (Name -> Bool) -> ConstrM ()
subElemFilter Name -> Bool
fltrf = (SCCtx -> (SCCtx, ())) -> ConstrM ()
forall a. (SCCtx -> (SCCtx, a)) -> ConstrM a
ConstrM ((SCCtx -> (SCCtx, ())) -> ConstrM ())
-> (SCCtx -> (SCCtx, ())) -> ConstrM ()
forall a b. (a -> b) -> a -> b
$ \SCCtx
c -> (SCCtx
c { cFilt = fltrf }, ())
paramVar :: String -> ConstrM ()
paramVar :: String -> ConstrM ()
paramVar String
pname = (SCCtx -> (SCCtx, ())) -> ConstrM ()
forall a. (SCCtx -> (SCCtx, a)) -> ConstrM a
ConstrM ((SCCtx -> (SCCtx, ())) -> ConstrM ())
-> (SCCtx -> (SCCtx, ())) -> ConstrM ()
forall a b. (a -> b) -> a -> b
$ \SCCtx
c -> (SCCtx
c { cVars = cVars c <> [ Right pname ] }, ())
paramSym :: String -> ConstrM ()
paramSym :: String -> ConstrM ()
paramSym String
pname = let psym :: Either Type String
psym = Type -> Either Type String
forall a b. a -> Either a b
Left (Type -> Either Type String) -> Type -> Either Type String
forall a b. (a -> b) -> a -> b
$ TyLit -> Type
TH.LitT (TyLit -> Type) -> TyLit -> Type
forall a b. (a -> b) -> a -> b
$ String -> TyLit
TH.StrTyLit String
pname
in (SCCtx -> (SCCtx, ())) -> ConstrM ()
forall a. (SCCtx -> (SCCtx, a)) -> ConstrM a
ConstrM ((SCCtx -> (SCCtx, ())) -> ConstrM ())
-> (SCCtx -> (SCCtx, ())) -> ConstrM ()
forall a b. (a -> b) -> a -> b
$ \SCCtx
c -> (SCCtx
c { cVars = cVars c <> [ psym ] }, ())
paramNat :: Integer -> ConstrM ()
paramNat :: Integer -> ConstrM ()
paramNat Integer
pnum = let pnat :: Either Type String
pnat = Type -> Either Type String
forall a b. a -> Either a b
Left (Type -> Either Type String) -> Type -> Either Type String
forall a b. (a -> b) -> a -> b
$ TyLit -> Type
TH.LitT (TyLit -> Type) -> TyLit -> Type
forall a b. (a -> b) -> a -> b
$ Integer -> TyLit
TH.NumTyLit Integer
pnum
in (SCCtx -> (SCCtx, ())) -> ConstrM ()
forall a. (SCCtx -> (SCCtx, a)) -> ConstrM a
ConstrM ((SCCtx -> (SCCtx, ())) -> ConstrM ())
-> (SCCtx -> (SCCtx, ())) -> ConstrM ()
forall a b. (a -> b) -> a -> b
$ \SCCtx
c -> (SCCtx
c { cVars = cVars c <> [ pnat ] }, ())
paramTH :: TH.Type -> ConstrM ()
paramTH :: Type -> ConstrM ()
paramTH Type
pty = (SCCtx -> (SCCtx, ())) -> ConstrM ()
forall a. (SCCtx -> (SCCtx, a)) -> ConstrM a
ConstrM ((SCCtx -> (SCCtx, ())) -> ConstrM ())
-> (SCCtx -> (SCCtx, ())) -> ConstrM ()
forall a b. (a -> b) -> a -> b
$ \SCCtx
c -> (SCCtx
c { cVars = cVars c <> [ Left pty ] }, ())
data SCCtx = SCCtx { SCCtx -> Name
cTgt :: Name
, SCCtx -> Name -> Bool
cFilt :: Name -> Bool
, SCCtx -> Either Type String
cSaytag :: Either TH.Type String
, SCCtx -> [Either Type String]
cVars :: [Either TH.Type String]
, SCCtx -> Maybe Type
cWrapper :: Maybe Type
}
sayableSubConstraints' :: (Name -> Bool)
-> Name
-> Either TH.Type String
-> Maybe TH.Type
-> [Either TH.Type String]
-> PredQ
sayableSubConstraints' :: (Name -> Bool)
-> Name
-> Either Type String
-> Maybe Type
-> [Either Type String]
-> PredQ
sayableSubConstraints' Name -> Bool
fltr Name
t Either Type String
tagName Maybe Type
mbWrapper [Either Type String]
varBindings = do
Type
v <- case Either Type String
tagName of
Left Type
x -> Type -> PredQ
forall a. a -> Q a
forall (m :: * -> *) a. Monad m => a -> m a
return Type
x
Right String
tn -> Name -> PredQ
forall (m :: * -> *). Quote m => Name -> m Type
varT (Name -> PredQ) -> Name -> PredQ
forall a b. (a -> b) -> a -> b
$ String -> Name
mkName String
tn
let vbs :: [Type]
vbs = let toTgt :: Either Type String -> Type
toTgt = \case
Left Type
ty -> Type
ty
Right String
nm -> Name -> Type
VarT (String -> Name
mkName String
nm)
in (Either Type String -> Type) -> [Either Type String] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Either Type String -> Type
toTgt [Either Type String]
varBindings
DatatypeInfo
rt <- Name -> Q DatatypeInfo
reifyDatatype Name
t
let cf' :: [Type]
cf' = [[Type]] -> [Type]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat (ConstructorInfo -> [Type]
constructorFields (ConstructorInfo -> [Type]) -> [ConstructorInfo] -> [[Type]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> DatatypeInfo -> [ConstructorInfo]
datatypeCons DatatypeInfo
rt)
[Type]
cf <- (Type -> PredQ) -> [Type] -> Q [Type]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM Type -> PredQ
resolveTypeSynonyms [Type]
cf'
let tsubmap :: Map Name Type
tsubmap = [(Name, Type)] -> Map Name Type
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList ([(Name, Type)] -> Map Name Type)
-> [(Name, Type)] -> Map Name Type
forall a b. (a -> b) -> a -> b
$ [Name] -> [Type] -> [(Name, Type)]
forall a b. [a] -> [b] -> [(a, b)]
zip (TyVarBndr_ () -> Name
forall flag. TyVarBndr_ flag -> Name
tvName (TyVarBndr_ () -> Name) -> [TyVarBndr_ ()] -> [Name]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> DatatypeInfo -> [TyVarBndr_ ()]
datatypeVars DatatypeInfo
rt) [Type]
vbs
let collectTC :: TH.Type -> Q [TH.Type]
collectTC :: Type -> Q [Type]
collectTC = \case
AppT Type
ListT (ConT Name
a) | Name
a Name -> Name -> Bool
forall a. Eq a => a -> a -> Bool
== ''Char -> [Type] -> Q [Type]
forall a. a -> Q a
forall (m :: * -> *) a. Monad m => a -> m a
return [Name -> Type
ConT ''String]
AppT Type
ListT Type
b -> Type -> Q [Type]
collectTC Type
b
AppT (ConT Name
a) Type
b | Name -> String
TH.nameBase Name
a String -> [String] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [ String
"NonEmpty"
, String
"Seq"
, String
"Set"
] -> Type -> Q [Type]
collectTC Type
b
x :: Type
x@(AppT (ConT Name
a) Type
b) -> if Name
a Name -> Name -> Bool
forall a. Eq a => a -> a -> Bool
== ''Maybe
then Type -> Q [Type]
collectTC Type
b
else [Type] -> Q [Type]
forall a. a -> Q a
forall (m :: * -> *) a. Monad m => a -> m a
return ([Type] -> Q [Type]) -> [Type] -> Q [Type]
forall a b. (a -> b) -> a -> b
$ if Name -> Bool
fltr Name
a then [Type
x] else []
(AppT Type
a Type
b) -> do [Type]
y <- Type -> Q [Type]
collectTC Type
a
[Type]
z <- Type -> Q [Type]
collectTC Type
b
[Type] -> Q [Type]
forall a. a -> Q a
forall (m :: * -> *) a. Monad m => a -> m a
return ([Type] -> Q [Type]) -> [Type] -> Q [Type]
forall a b. (a -> b) -> a -> b
$ [[Type]] -> [Type]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ((\Type
x -> Type -> Type -> Type
AppT Type
x (Type -> Type) -> [Type] -> [Type]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Type]
z) (Type -> [Type]) -> [Type] -> [[Type]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Type]
y)
x :: Type
x@(ConT Name
a) -> [Type] -> Q [Type]
forall a. a -> Q a
forall (m :: * -> *) a. Monad m => a -> m a
return ([Type] -> Q [Type]) -> [Type] -> Q [Type]
forall a b. (a -> b) -> a -> b
$ if Name -> Bool
fltr Name
a then [Type
x] else []
x :: Type
x@(VarT Name
a) -> [Type] -> Q [Type]
forall a. a -> Q a
forall (m :: * -> *) a. Monad m => a -> m a
return ([Type] -> Q [Type]) -> [Type] -> Q [Type]
forall a b. (a -> b) -> a -> b
$ if Name -> Bool
fltr Name
a then [Type
x] else []
Type
x -> [Type] -> Q [Type]
forall a. a -> Q a
forall (m :: * -> *) a. Monad m => a -> m a
return [Type
x]
[Type]
tc <- (Type -> Type) -> [Type] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Map Name Type -> Type -> Type
forall a. TypeSubstitution a => Map Name Type -> a -> a
applySubstitution Map Name Type
tsubmap) ([Type] -> [Type]) -> ([[Type]] -> [Type]) -> [[Type]] -> [Type]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[Type]] -> [Type]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[Type]] -> [Type]) -> Q [[Type]] -> Q [Type]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((Type -> Q [Type]) -> [Type] -> Q [[Type]]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM Type -> Q [Type]
collectTC [Type]
cf)
let mkConstrTpl :: Type -> [Type] -> Type
mkConstrTpl Type
elem0 [Type]
lst =
if [Type] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Type]
lst then Type
elem0
else let ([Type]
lst1, [Type]
lst2) = Int -> [Type] -> ([Type], [Type])
forall a. Int -> [a] -> ([a], [a])
splitAt Int
60 [Type]
lst
l1len :: Int
l1len = [Type] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
lst1
base :: Type
base = Type -> Type -> Type
AppT (Int -> Type
TupleT (Int
l1len Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)) Type
elem0
next :: Type -> Type -> Type
next Type
tc' Type
p' = Type -> Type -> Type
AppT Type
p' (Name -> [Type] -> Type
classPred ''Sayable [Type
v, Type
tc'])
in Type -> [Type] -> Type
mkConstrTpl ((Type -> Type -> Type) -> Type -> [Type] -> Type
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Type -> Type -> Type
next Type
base [Type]
lst1) [Type]
lst2
let p :: Type
p = Type -> [Type] -> Type
mkConstrTpl (Int -> Type
TupleT Int
0) ((Type -> Type)
-> (Type -> Type -> Type) -> Maybe Type -> Type -> Type
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Type -> Type
forall a. a -> a
id Type -> Type -> Type
AppT Maybe Type
mbWrapper (Type -> Type) -> [Type] -> [Type]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Type]
tc)
let pv :: Type
pv = Type -> [Type] -> Type
mkConstrTpl Type
p (Name -> Type
VarT (Name -> Type) -> (String -> Name) -> String -> Type
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Name
mkName (String -> Type) -> [String] -> [Type]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Either Type String] -> [String]
forall a b. [Either a b] -> [b]
rights [Either Type String]
varBindings)
Type -> PredQ
forall a. a -> Q a
forall (m :: * -> *) a. Monad m => a -> m a
return Type
pv