{-# OPTIONS -Wall #-}
{-# OPTIONS -Wno-compat #-}
{-# OPTIONS -Wincomplete-record-updates #-}
{-# OPTIONS -Wincomplete-uni-patterns #-}
{-# OPTIONS -Wredundant-constraints #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE NoOverloadedLists #-}
{-# LANGUAGE NoStarIsType #-}
module Predicate.Prelude (
type (&&)
, type (||)
, type (~>)
, Not
, Ands
, Ors
, Asc
, Asc'
, Desc
, Desc'
, Between
, BetweenA
, type (<..>)
, All
, Any
, AllPositive
, Positive
, AllNegative
, Negative
, AndA
, type (&*)
, OrA
, type (|+)
, IdBool
, Re
, Re'
, Rescan
, Rescan'
, RescanRanges
, RescanRanges'
, Resplit
, Resplit'
, ReplaceAll
, ReplaceAll'
, ReplaceOne
, ReplaceOne'
, ReplaceAllString
, ReplaceAllString'
, ReplaceOneString
, ReplaceOneString'
, ReplaceFn
, ReplaceFn1
, ReplaceFn2
, ReplaceFn3
, Fst
, Snd
, Thd
, L1
, L2
, L3
, L4
, L5
, L6
, Dup
, Swap
, SwapC(..)
, Assoc
, Unassoc
, Pairs
, IsLower
, IsUpper
, IsDigit
, IsSpace
, IsPunctuation
, IsControl
, IsHexDigit
, IsOctDigit
, IsSeparator
, IsLatin1
, IsLowerAll
, IsUpperAll
, IsDigitAll
, IsSpaceAll
, IsPunctuationAll
, IsControlAll
, IsHexDigitAll
, IsOctDigitAll
, IsSeparatorAll
, IsLatin1All
, FormatTimeP
, ParseTimeP
, ParseTimeP'
, ParseTimes
, ParseTimes'
, MkDay
, MkDay'
, UnMkDay
, MkDayExtra
, MkDayExtra'
, ToDay
, ToTime
, MkTime
, MkTime'
, UnMkTime
, PosixToUTCTime
, UTCTimeToPosix
, type (+)
, type (-)
, type (*)
, type (/)
, Negate
, Abs
, Signum
, FromInteger
, FromInteger'
, FromIntegral
, FromIntegral'
, Truncate
, Truncate'
, Ceiling
, Ceiling'
, Floor
, Floor'
, Even
, Odd
, Div
, Mod
, DivMod
, QuotRem
, Quot
, Rem
, LogBase
, type (^)
, type (**)
, type (%)
, type (-%)
, ToRational
, FromRational
, FromRational'
, MkProxy
, ProxyT
, ProxyT'
, Unproxy
, ShowP
, ReadP
, ReadP'
, ReadQ
, ReadQ'
, ReadMaybe
, ReadMaybe'
, ReadBase
, ReadBase'
, ShowBase
, ParseJson'
, ParseJson
, EncodeJson
, EncodeJsonFile
, ParseJsonFile'
, ParseJsonFile
, type (&&&)
, type (***)
, First
, Second
, type (|||)
, type (+++)
, type (>)
, type (>=)
, type (==)
, type (/=)
, type (<=)
, type (<)
, type (>~)
, type (>=~)
, type (==~)
, type (/=~)
, type (<=~)
, type (<~)
, Gt
, Ge
, Same
, Le
, Lt
, Ne
, type (==!)
, OrdP
, OrdA'
, OrdA
, OrdI
, type (===~)
, Cmp
, CmpI
, Succ
, Pred
, FromEnum
, ToEnum
, ToEnum'
, EnumFromTo
, SuccB
, SuccB'
, PredB
, PredB'
, ToEnumBDef
, ToEnumBDef'
, ToEnumBFail
, Unwrap
, Wrap
, Wrap'
, Coerce
, Coerce2
, Map
, Concat
, ConcatMap
, Partition
, GroupOn
, Filter
, Break
, Span
, Intercalate
, Elem
, Inits
, Tails
, Ones
, OneP
, Len
, Length
, PadL
, PadR
, Cycle
, SplitAts
, SplitAt
, ChunksOf
, Rotate
, Take
, Drop
, Min
, Max
, Sum
, Product
, IsEmpty
, Null
, Null'
, ToList
, ToList'
, IToList
, IToList'
, FromList
, EmptyList
, EmptyList'
, Singleton
, Reverse
, ReverseL
, SortBy
, SortOn
, SortOnDesc
, Remove
, Keep
, ToListExt
, FromListExt
, MkNothing
, MkNothing'
, MkJust
, IsNothing
, IsJust
, MapMaybe
, CatMaybes
, Just
, JustDef
, JustFail
, MaybeIn
, MaybeBool
, PartitionEithers
, IsLeft
, IsRight
, MkLeft
, MkLeft'
, MkRight
, MkRight'
, Left'
, Right'
, LeftDef
, LeftFail
, RightDef
, RightFail
, EitherBool
, EitherIn
, type (<>)
, MConcat
, STimes
, SapA
, SapA'
, MEmptyT
, MEmptyT'
, MEmptyP
, MEmpty2
, MEmpty2'
, Ix
, Ix'
, IxL
, type (!!)
, type (!!?)
, Lookup
, LookupDef
, LookupDef'
, LookupFail
, LookupFail'
, type (:+)
, type (+:)
, type (++)
, Uncons
, Unsnoc
, Head
, Tail
, Init
, Last
, HeadDef
, HeadFail
, TailDef
, TailFail
, LastDef
, LastFail
, InitDef
, InitFail
, PartitionThese
, Thiss
, Thats
, Theses
, This'
, That'
, These'
, IsThis
, IsThat
, IsThese
, MkThis
, MkThis'
, MkThat
, MkThat'
, MkThese
, ThisDef
, ThisFail
, ThatDef
, ThatFail
, TheseDef
, TheseFail
, TheseIn
, TheseId
, TheseX
, Scanl
, ScanN
, ScanNA
, FoldN
, FoldL
, Unfoldr
, IterateN
, IterateUntil
, IterateWhile
, IterateNWhile
, IterateNUntil
, Fail
, Failp
, Failt
, FailS
, Catch
, Catch'
, ZipThese
, ZipL
, ZipR
, Zip
, Unzip
, Unzip3
, If
, Case
, Case'
, Case''
, Guards
, GuardsQuick
, Guard
, ExitWhen
, GuardSimple
, GuardsN
, GuardsDetail
, Bools
, BoolsQuick
, BoolsN
, ReadFile
, FileExists
, ReadDir
, DirExists
, ReadEnv
, ReadEnvAll
, TimeUtc
, TimeZt
, AppendFile
, WriteFile
, WriteFile'
, Stdout
, Stderr
, Stdin
, ReadIO
, ReadIO'
, ToLower
, ToUpper
, ToTitle
, TrimBoth
, TrimL
, TrimR
, StripR
, StripL
, IsPrefix
, IsInfix
, IsSuffix
, IsPrefixI
, IsInfixI
, IsSuffixI
, ToString
, FromString
, FromString'
, PrintF
, PrintL
, PrintT
, Pure
, Pure2
, FoldMap
, type (<$)
, type (<*)
, type (*>)
, FMapFst
, FMapSnd
, Sequence
, Traverse
, Join
, EmptyT
, type (<|>)
, Extract
, Duplicate
, type ($)
, type (&)
, Do
, Dot
, RDot
, type (>>)
, type (<<)
, type (>>>)
, DoN
, type ($$)
, type ($&)
, K
, Hide
, Hole
, Skip
, type (|>)
, type (>|)
, type (>|>)
, Uncurry
, Para
, ParaN
, Repeat
, Both
, Prime
, PrimeNext
, Luhn
, Char1
, Tuple2
, Tuple3
, Tuple4
, Tuple5
, Tuple6
) where
import Predicate.Core
import Predicate.Util
import Safe (succMay, predMay, toEnumMay)
import GHC.TypeLits (Symbol,Nat,KnownSymbol,KnownNat,ErrorMessage((:$$:),(:<>:)))
import qualified GHC.TypeLits as GL
import Control.Lens hiding (iall)
import Data.List
import qualified Data.Text.Lens as DTL
import Data.Proxy
import Control.Applicative
import Data.Typeable
import Control.Monad.Except
import qualified Control.Exception as E
import Data.Kind (Type)
import qualified Text.Regex.PCRE.Heavy as RH
import Data.String
import Data.Foldable
import Data.Maybe
import Control.Arrow
import qualified Data.Semigroup as SG
import Numeric
import Data.Char
import Data.Function
import Data.These (These(..))
import Data.Ratio
import Data.Time
import Data.Coerce
import Data.Void
import qualified Data.Sequence as Seq
import Text.Printf
import System.Directory
import Control.Comonad
import System.IO
import System.Environment
import qualified GHC.Exts as GE
import Data.Bool
import Data.Either
import qualified Data.Type.Equality as DE
import Data.Time.Calendar.WeekDate
import qualified Data.Time.Clock.System as CP
import qualified Data.Time.Clock.POSIX as P
import qualified Data.Aeson as A
import qualified Data.ByteString.Char8 as BS8
import qualified Data.ByteString.Lazy.Char8 as BL8
import qualified Data.Text as T
import qualified Data.Text.Lazy as TL
import qualified Data.Map.Strict as M
data Asc
type AscT = All (Fst Id <= Snd Id) Pairs
instance P AscT x => P Asc x where
type PP Asc x = PP AscT x
eval _ = evalBool (Proxy @AscT)
data Asc'
type AscT' = All (Fst Id < Snd Id) Pairs
instance P AscT' x => P Asc' x where
type PP Asc' x = PP AscT' x
eval _ = evalBool (Proxy @AscT')
data Desc
type DescT = All (Fst Id >= Snd Id) Pairs
instance P DescT x => P Desc x where
type PP Desc x = PP DescT x
eval _ = evalBool (Proxy @DescT)
data Desc'
type DescT' = All (Fst Id > Snd Id) Pairs
instance P DescT' x => P Desc' x where
type PP Desc' x = PP DescT' x
eval _ = evalBool (Proxy @DescT')
data Between p q r
instance (Ord (PP p x)
, Show (PP p x)
, PP r x ~ PP p x
, PP r x ~ PP q x
, P p x
, P q x
, P r x
) => P (Between p q r) x where
type PP (Between p q r) x = Bool
eval _ opts x = do
let msg0 = "Between"
rr <- eval (Proxy @r) opts x
case getValueLR opts msg0 rr [] of
Left e -> pure e
Right r -> do
lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x [hh rr]
pure $ case lr of
Left e -> e
Right (p,q,pp,qq) ->
let hhs = [hh rr, hh pp, hh qq]
in if p <= r && r <= q then mkNodeB opts True (show p <> " <= " <> show r <> " <= " <> show q) hhs
else if p > r then mkNodeB opts False (show p <> " <= " <> show r) hhs
else mkNodeB opts False (show r <> " <= " <> show q) hhs
data p <..> q
infix 4 <..>
type BetweenT p q = Between p q Id
instance P (BetweenT p q) x => P (p <..> q) x where
type PP (p <..> q) x = PP (BetweenT p q) x
eval _ = evalBool (Proxy @(BetweenT p q))
data BetweenA p q
instance (PP p x ~ (a,a')
, P q x
, PP q x ~ a
, Ord a
, a ~ a'
, Show a
, P p x
) => P (BetweenA p q) x where
type PP (BetweenA p q) x = Bool
eval _ opts x = do
let msg0 = "BetweenA"
lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
pure $ case lr of
Left e -> e
Right ((p1,p2),q,pp,qq) ->
[hh pp, hh qq] & if p1 <= q && q <= p2 then mkNodeB opts True (show p1 <> " <= " <> show q <> " <= " <> show p2)
else if p1 > q then mkNodeB opts False (show p1 <> " <= " <> show q)
else mkNodeB opts False (show q <> " <= " <> show p2)
data All p q
instance (P p a
, PP p a ~ Bool
, PP q x ~ f a
, P q x
, Show a
, Foldable f
) => P (All p q) x where
type PP (All p q) x = Bool
eval _ opts x = do
let msg0 = "All"
qq <- eval (Proxy @q) opts x
case getValueLR opts msg0 qq [] of
Left e -> pure e
Right q ->
case chkSize opts msg0 q [hh qq] of
Left e -> pure e
Right () -> do
ts <- zipWithM (\i a -> ((i, a),) <$> evalBool (Proxy @p) opts a) [0::Int ..] (toList q)
pure $ case splitAndAlign opts msg0 ts of
Left e -> e
Right abcs ->
let hhs = hh qq : map (hh . fixit) ts
msg1 = msg0 ++ "(" ++ show (length q) ++ ")"
in case find (not . view _1) abcs of
Nothing -> mkNodeB opts True msg1 hhs
Just (_,(i,_),tt) ->
mkNodeB opts False (msg1 <> " i=" ++ showIndex i ++ " " <> topMessage tt) hhs
showIndex :: (Show i, Num i) => i -> String
showIndex i = show (i+0)
data Any p q
instance (P p a
, PP p a ~ Bool
, PP q x ~ f a
, P q x
, Show a
, Foldable f
) => P (Any p q) x where
type PP (Any p q) x = Bool
eval _ opts x = do
let msg0 = "Any"
qq <- eval (Proxy @q) opts x
case getValueLR opts msg0 qq [] of
Left e -> pure e
Right q ->
case chkSize opts msg0 q [hh qq] of
Left e -> pure e
Right () -> do
ts <- zipWithM (\i a -> ((i, a),) <$> evalBool (Proxy @p) opts a) [0::Int ..] (toList q)
pure $ case splitAndAlign opts msg0 ts of
Left e -> e
Right abcs ->
let hhs = hh qq : map (hh . fixit) ts
msg1 = msg0 ++ "(" ++ show (length q) ++ ")"
in case find (view _1) abcs of
Nothing -> mkNodeB opts False msg1 hhs
Just (_,(i,_),tt) ->
mkNodeB opts True (msg1 <> " i=" ++ showIndex i ++ " " <> topMessage tt) hhs
data AllPositive
type AllPositiveT = All Positive Id
instance P AllPositiveT x => P AllPositive x where
type PP AllPositive x = PP AllPositiveT x
eval _ = evalBool (Proxy @AllPositiveT)
data AllNegative
type AllNegativeT = All Negative Id
instance P AllNegativeT x => P AllNegative x where
type PP AllNegative x = PP AllNegativeT x
eval _ = evalBool (Proxy @AllNegativeT)
type Positive = Gt 0
type Negative = Lt 0
data Unzip
type UnzipT = '(Map (Fst Id) Id, Map (Snd Id) Id)
instance P UnzipT x => P Unzip x where
type PP Unzip x = PP UnzipT x
eval _ = eval (Proxy @UnzipT)
data Unzip3
type Unzip3T = '(Map (Fst Id) Id, Map (Snd Id) Id, Map (Thd Id) Id)
instance P Unzip3T x => P Unzip3 x where
type PP Unzip3 x = PP Unzip3T x
eval _ = eval (Proxy @Unzip3T)
data Re' (rs :: [ROpt]) p q
data Re p q
instance (GetROpts rs
, PP p x ~ String
, PP q x ~ String
, P p x
, P q x
) => P (Re' rs p q) x where
type PP (Re' rs p q) x = Bool
eval _ opts x = do
let msg0 = "Re" <> (if null rs then "' " <> show rs else "")
rs = getROpts @rs
lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
pure $ case lr of
Left e -> e
Right (p,q,pp,qq) ->
let msg1 = msg0 <> " (" <> p <> ")"
hhs = [hh pp, hh qq]
in case compileRegex @rs opts msg1 p hhs of
Left tta -> tta
Right regex ->
let b = q RH.=~ regex
in mkNodeB opts b (msg1 <> showLit1 opts " | " q) hhs
type ReT p q = Re' '[] p q
instance P (ReT p q) x => P (Re p q) x where
type PP (Re p q) x = PP (ReT p q) x
eval _ = evalBool (Proxy @(ReT p q))
data Rescan' (rs :: [ROpt]) p q
instance (GetROpts rs
, PP p x ~ String
, PP q x ~ String
, P p x
, P q x
) => P (Rescan' rs p q) x where
type PP (Rescan' rs p q) x = [(String, [String])]
eval _ opts x = do
let msg0 = "Rescan" <> (if null rs then "' " <> show rs else "")
rs = getROpts @rs
lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
pure $ case lr of
Left e -> e
Right (p,q,pp,qq) ->
let msg1 = msg0 <> " (" <> p <> ")"
hhs = [hh pp, hh qq]
in case compileRegex @rs opts msg1 p hhs of
Left tta -> tta
Right regex ->
case splitAt (oRecursion opts) $ RH.scan regex q of
(b, _:_) -> mkNode opts (FailT "Regex looping") (msg1 <> " Looping? " <> show (take 10 b) <> "..." <> show1 opts " | " q) hhs
([], _) ->
mkNode opts (FailT "Regex no results") (msg1 <> " no match" <> show1 opts " | " q) [hh pp, hh qq]
(b, _) -> mkNode opts (PresentT b) (lit01 opts msg1 b q) [hh pp, hh qq]
data Rescan p q
type RescanT p q = Rescan' '[] p q
instance P (RescanT p q) x => P (Rescan p q) x where
type PP (Rescan p q) x = PP (RescanT p q) x
eval _ = eval (Proxy @(RescanT p q))
data RescanRanges' (rs :: [ROpt]) p q
instance (GetROpts rs
, PP p x ~ String
, PP q x ~ String
, P p x
, P q x
) => P (RescanRanges' rs p q) x where
type PP (RescanRanges' rs p q) x = [((Int,Int), [(Int,Int)])]
eval _ opts x = do
let msg0 = "RescanRanges" <> (if null rs then "' " <> show rs else "")
rs = getROpts @rs
lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
pure $ case lr of
Left e -> e
Right (p,q,pp,qq) ->
let msg1 = msg0 <> " (" <> p <> ")"
hhs = [hh pp, hh qq]
in case compileRegex @rs opts msg1 p hhs of
Left tta -> tta
Right regex ->
case splitAt (oRecursion opts) $ RH.scanRanges regex q of
(b, _:_) -> mkNode opts (FailT "Regex looping") (msg1 <> " Looping? " <> show (take 10 b) <> "..." <> show1 opts " | " q) hhs
([], _) ->
mkNode opts (FailT "Regex no results") (msg1 <> " no match" <> show1 opts " | " q) hhs
(b, _) -> mkNode opts (PresentT b) (lit01 opts msg1 b q) hhs
data RescanRanges p q
type RescanRangesT p q = RescanRanges' '[] p q
instance P (RescanRangesT p q) x => P (RescanRanges p q) x where
type PP (RescanRanges p q) x = PP (RescanRangesT p q) x
eval _ = eval (Proxy @(RescanRangesT p q))
data Resplit' (rs :: [ROpt]) p q
instance (GetROpts rs
, PP p x ~ String
, PP q x ~ String
, P p x
, P q x
) => P (Resplit' rs p q) x where
type PP (Resplit' rs p q) x = [String]
eval _ opts x = do
let msg0 = "Resplit" <> (if null rs then "' " <> show rs else "")
rs = getROpts @rs
lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
pure $ case lr of
Left e -> e
Right (p,q,pp,qq) ->
let msg1 = msg0 <> " (" <> p <> ")"
hhs = [hh pp, hh qq]
in case compileRegex @rs opts msg1 p hhs of
Left tta -> tta
Right regex ->
case splitAt (oRecursion opts) $ RH.split regex q of
(b, _:_) -> mkNode opts (FailT "Regex looping") (msg1 <> " Looping? " <> show (take 10 b) <> "..." <> show1 opts " | " q) hhs
([], _) ->
mkNode opts (FailT "Regex no results") (msg1 <> " no match" <> show1 opts " | " q) hhs
(b, _) -> mkNode opts (PresentT b) (lit01 opts msg1 b q) hhs
data Resplit p q
type ResplitT p q = Resplit' '[] p q
instance P (ResplitT p q) x => P (Resplit p q) x where
type PP (Resplit p q) x = PP (ResplitT p q) x
eval _ = eval (Proxy @(ResplitT p q))
data ReplaceImpl (alle :: Bool) (rs :: [ROpt]) p q r
instance (GetBool b
, GetROpts rs
, PP p x ~ String
, PP q x ~ RReplace
, PP r x ~ String
, P p x
, P q x
, P r x
) => P (ReplaceImpl b rs p q r) x where
type PP (ReplaceImpl b rs p q r) x = String
eval _ opts x = do
let msg0 = "Replace" <> (if alle then "All" else "One") <> (if null rs then "' " <> show rs else "")
rs = getROpts @rs
alle = getBool @b
lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
case lr of
Left e -> pure e
Right (p,q,pp,qq) ->
let msg1 = msg0 <> " (" <> p <> ")"
hhs = [hh pp, hh qq]
in case compileRegex @rs opts msg1 p hhs of
Left tta -> pure tta
Right regex -> do
rr <- eval (Proxy @r) opts x
pure $ case getValueLR opts msg0 rr hhs of
Left e -> e
Right r ->
let ret :: String
ret = case q of
RReplace o s ->
let g fn = (if alle then RH.gsub else RH.sub) regex fn r
in g (case o of
RPrepend -> (s <>)
ROverWrite -> const s
RAppend -> (<> s))
RReplace1 s -> (if alle then RH.gsub else RH.sub) regex s r
RReplace2 s -> (if alle then RH.gsub else RH.sub) regex s r
RReplace3 s -> (if alle then RH.gsub else RH.sub) regex s r
in mkNode opts (PresentT ret) (msg1 <> showLit0 opts " " r <> showLit1 opts " | " ret) (hhs <> [hh rr])
data ReplaceAll' (rs :: [ROpt]) p q r
type ReplaceAllT' (rs :: [ROpt]) p q r = ReplaceImpl 'True rs p q r
instance P (ReplaceAllT' rs p q r) x => P (ReplaceAll' rs p q r) x where
type PP (ReplaceAll' rs p q r) x = PP (ReplaceAllT' rs p q r) x
eval _ = eval (Proxy @(ReplaceAllT' rs p q r))
data ReplaceAll p q r
type ReplaceAllT p q r = ReplaceAll' '[] p q r
instance P (ReplaceAllT p q r) x => P (ReplaceAll p q r) x where
type PP (ReplaceAll p q r) x = PP (ReplaceAllT p q r) x
eval _ = eval (Proxy @(ReplaceAllT p q r))
data ReplaceOne' (rs :: [ROpt]) p q r
type ReplaceOneT' (rs :: [ROpt]) p q r = ReplaceImpl 'False rs p q r
instance P (ReplaceOneT' rs p q r) x => P (ReplaceOne' rs p q r) x where
type PP (ReplaceOne' rs p q r) x = PP (ReplaceOneT' rs p q r) x
eval _ = eval (Proxy @(ReplaceOneT' rs p q r))
data ReplaceOne p q r
type ReplaceOneT p q r = ReplaceOne' '[] p q r
instance P (ReplaceOneT p q r) x => P (ReplaceOne p q r) x where
type PP (ReplaceOne p q r) x = PP (ReplaceOneT p q r) x
eval _ = eval (Proxy @(ReplaceOneT p q r))
data ReplaceAllString' (rs :: [ROpt]) (o :: ReplaceFnSub) p q r
type ReplaceAllStringT' (rs :: [ROpt]) (o :: ReplaceFnSub) p q r = ReplaceAll' rs p (ReplaceFn o q) r
instance P (ReplaceAllStringT' rs o p q r) x => P (ReplaceAllString' rs o p q r) x where
type PP (ReplaceAllString' rs o p q r) x = PP (ReplaceAllStringT' rs o p q r) x
eval _ = eval (Proxy @(ReplaceAllStringT' rs o p q r))
data ReplaceAllString o p q r
type ReplaceAllStringT o p q r = ReplaceAllString' '[] o p q r
instance P (ReplaceAllStringT o p q r) x => P (ReplaceAllString o p q r) x where
type PP (ReplaceAllString o p q r) x = PP (ReplaceAllStringT o p q r) x
eval _ = eval (Proxy @(ReplaceAllStringT o p q r))
data ReplaceOneString' (rs :: [ROpt]) (o :: ReplaceFnSub) p q r
type ReplaceOneStringT' (rs :: [ROpt]) (o :: ReplaceFnSub) p q r = ReplaceOne' rs p (ReplaceFn o q) r
instance P (ReplaceOneStringT' rs o p q r) x => P (ReplaceOneString' rs o p q r) x where
type PP (ReplaceOneString' rs o p q r) x = PP (ReplaceOneStringT' rs o p q r) x
eval _ = eval (Proxy @(ReplaceOneStringT' rs o p q r))
data ReplaceOneString (o :: ReplaceFnSub) p q r
type ReplaceOneStringT (o :: ReplaceFnSub) p q r = ReplaceOneString' '[] o p q r
instance P (ReplaceOneStringT o p q r) x => P (ReplaceOneString o p q r) x where
type PP (ReplaceOneString o p q r) x = PP (ReplaceOneStringT o p q r) x
eval _ = eval (Proxy @(ReplaceOneStringT o p q r))
data ReplaceFn (o :: ReplaceFnSub) p
instance (ReplaceFnSubC r
, PP p x ~ String
, P p x) => P (ReplaceFn r p) x where
type PP (ReplaceFn r p) x = RReplace
eval _ opts x = do
let msg0 = "ReplaceFn"
pp <- eval (Proxy @p) opts x
pure $ case getValueLR opts msg0 pp [] of
Left e -> e
Right p ->
let b = RReplace (getReplaceFnSub @r) p
in mkNode opts (PresentT b) (msg0 <> show1 opts " | " p) [hh pp]
data ReplaceFn1 p
instance (PP p x ~ (String -> [String] -> String)
, P p x) => P (ReplaceFn1 p) x where
type PP (ReplaceFn1 p) x = RReplace
eval _ opts x = do
let msg0 = "ReplaceFn1 (String -> [String] -> String)"
pp <- eval (Proxy @p) opts x
pure $ case getValueLR opts msg0 pp [] of
Left e -> e
Right f -> mkNode opts (PresentT (RReplace1 f)) msg0 [hh pp]
data ReplaceFn2 p
instance (PP p x ~ (String -> String)
, P p x) => P (ReplaceFn2 p) x where
type PP (ReplaceFn2 p) x = RReplace
eval _ opts x = do
let msg0 = "ReplaceFn2 (String -> String)"
pp <- eval (Proxy @p) opts x
pure $ case getValueLR opts msg0 pp [] of
Left e -> e
Right f -> mkNode opts (PresentT (RReplace2 f)) msg0 [hh pp]
data ReplaceFn3 p
instance (PP p x ~ ([String] -> String)
, P p x) => P (ReplaceFn3 p) x where
type PP (ReplaceFn3 p) x = RReplace
eval _ opts x = do
let msg0 = "ReplaceFn3 ([String] -> String)"
pp <- eval (Proxy @p) opts x
pure $ case getValueLR opts msg0 pp [] of
Left e -> e
Right f -> mkNode opts (PresentT (RReplace3 f)) msg0 [hh pp]
data IsCharSet (cs :: CharSet)
instance (x ~ Char, GetCharSet cs) => P (IsCharSet cs) x where
type PP (IsCharSet cs) x = Bool
eval _ opts c =
let msg0 = "Is" ++ drop 1 (show cs)
(cs,f) = getCharSet @cs
b = f c
in pure $ mkNodeB opts b (msg0 <> show1 opts " | " [c]) []
data IsLower
type IsLowerT = IsCharSet 'CLower
instance P IsLowerT x => P IsLower x where
type PP IsLower x = PP IsLowerT x
eval _ = evalBool (Proxy @IsLowerT)
data IsUpper
type IsUpperT = IsCharSet 'CUpper
instance P IsUpperT x => P IsUpper x where
type PP IsUpper x = PP IsUpperT x
eval _ = evalBool (Proxy @IsUpperT)
data IsDigit
type IsDigitT = IsCharSet 'CNumber
instance P IsDigitT x => P IsDigit x where
type PP IsDigit x = Bool
eval _ = evalBool (Proxy @IsDigitT)
data IsSpace
type IsSpaceT = IsCharSet 'CSpace
instance P IsSpaceT x => P IsSpace x where
type PP IsSpace x = Bool
eval _ = evalBool (Proxy @IsSpaceT)
data IsPunctuation
type IsPunctuationT = IsCharSet 'CPunctuation
instance P IsPunctuationT x => P IsPunctuation x where
type PP IsPunctuation x = Bool
eval _ = evalBool (Proxy @IsPunctuationT)
data IsControl
type IsControlT = IsCharSet 'CControl
instance P IsControlT x => P IsControl x where
type PP IsControl x = Bool
eval _ = evalBool (Proxy @IsControlT)
data IsHexDigit
type IsHexDigitT = IsCharSet 'CHexDigit
instance P IsHexDigitT x => P IsHexDigit x where
type PP IsHexDigit x = Bool
eval _ = evalBool (Proxy @IsHexDigitT)
data IsOctDigit
type IsOctDigitT = IsCharSet 'COctDigit
instance P IsOctDigitT x => P IsOctDigit x where
type PP IsOctDigit x = Bool
eval _ = evalBool (Proxy @IsOctDigitT)
data IsSeparator
type IsSeparatorT = IsCharSet 'CSeparator
instance P IsSeparatorT x => P IsSeparator x where
type PP IsSeparator x = Bool
eval _ = evalBool (Proxy @IsSeparatorT)
data IsLatin1
type IsLatin1T = IsCharSet 'CLatin1
instance P IsLatin1T x => P IsLatin1 x where
type PP IsLatin1 x = Bool
eval _ = evalBool (Proxy @IsLatin1T)
data IsCharSetAll (cs :: CharSet)
instance (GetCharSet cs
, Show a
, DTL.IsText a
) => P (IsCharSetAll cs) a where
type PP (IsCharSetAll cs) a = Bool
eval _ opts as =
let b = allOf DTL.text f as
msg0 = "Is" ++ drop 1 (show cs) ++ "All"
(cs,f) = getCharSet @cs
in pure $ mkNodeB opts b (msg0 <> show1 opts " | " as) []
data CharSet = CLower
| CUpper
| CNumber
| CSpace
| CPunctuation
| CControl
| CHexDigit
| COctDigit
| CSeparator
| CLatin1
deriving Show
class GetCharSet (cs :: CharSet) where
getCharSet :: (CharSet, Char -> Bool)
instance GetCharSet 'CLower where
getCharSet = (CLower, isLower)
instance GetCharSet 'CUpper where
getCharSet = (CUpper, isUpper)
instance GetCharSet 'CNumber where
getCharSet = (CNumber, isNumber)
instance GetCharSet 'CSpace where
getCharSet = (CSpace, isSpace)
instance GetCharSet 'CPunctuation where
getCharSet = (CPunctuation, isPunctuation)
instance GetCharSet 'CControl where
getCharSet = (CControl, isControl)
instance GetCharSet 'CHexDigit where
getCharSet = (CHexDigit, isHexDigit)
instance GetCharSet 'COctDigit where
getCharSet = (COctDigit, isOctDigit)
instance GetCharSet 'CSeparator where
getCharSet = (CSeparator, isSeparator)
instance GetCharSet 'CLatin1 where
getCharSet = (CLatin1, isLatin1)
data IsLowerAll
type IsLowerAllT = IsCharSetAll 'CLower
instance P IsLowerAllT x => P IsLowerAll x where
type PP IsLowerAll x = PP IsLowerAllT x
eval _ = evalBool (Proxy @IsLowerAllT)
data IsUpperAll
type IsUpperAllT = IsCharSetAll 'CUpper
instance P IsUpperAllT x => P IsUpperAll x where
type PP IsUpperAll x = PP IsUpperAllT x
eval _ = evalBool (Proxy @IsUpperAllT)
data IsDigitAll
type IsDigitAllT = IsCharSetAll 'CNumber
instance P IsDigitAllT x => P IsDigitAll x where
type PP IsDigitAll x = Bool
eval _ = evalBool (Proxy @IsDigitAllT)
data IsSpaceAll
type IsSpaceAllT = IsCharSetAll 'CSpace
instance P IsSpaceAllT x => P IsSpaceAll x where
type PP IsSpaceAll x = Bool
eval _ = evalBool (Proxy @IsSpaceAllT)
data IsPunctuationAll
type IsPunctuationAllT = IsCharSetAll 'CPunctuation
instance P IsPunctuationAllT x => P IsPunctuationAll x where
type PP IsPunctuationAll x = Bool
eval _ = evalBool (Proxy @IsPunctuationAllT)
data IsControlAll
type IsControlAllT = IsCharSetAll 'CControl
instance P IsControlAllT x => P IsControlAll x where
type PP IsControlAll x = Bool
eval _ = evalBool (Proxy @IsControlAllT)
data IsHexDigitAll
type IsHexDigitAllT = IsCharSetAll 'CHexDigit
instance P IsHexDigitAllT x => P IsHexDigitAll x where
type PP IsHexDigitAll x = Bool
eval _ = evalBool (Proxy @IsHexDigitAllT)
data IsOctDigitAll
type IsOctDigitAllT = IsCharSetAll 'COctDigit
instance P IsOctDigitAllT x => P IsOctDigitAll x where
type PP IsOctDigitAll x = Bool
eval _ = evalBool (Proxy @IsOctDigitAllT)
data IsSeparatorAll
type IsSeparatorAllT = IsCharSetAll 'CSeparator
instance P IsSeparatorAllT x => P IsSeparatorAll x where
type PP IsSeparatorAll x = Bool
eval _ = evalBool (Proxy @IsSeparatorAllT)
data IsLatin1All
type IsLatin1AllT = IsCharSetAll 'CLatin1
instance P IsLatin1AllT x => P IsLatin1All x where
type PP IsLatin1All x = Bool
eval _ = evalBool (Proxy @IsLatin1AllT)
data ToLower
instance (Show a, DTL.IsText a) => P ToLower a where
type PP ToLower a = a
eval _ opts as =
let msg0 = "ToLower"
xs = as & DTL.text %~ toLower
in pure $ mkNode opts (PresentT xs) (show01 opts msg0 xs as) []
data ToUpper
instance (Show a, DTL.IsText a) => P ToUpper a where
type PP ToUpper a = a
eval _ opts as =
let msg0 = "ToUpper"
xs = as & DTL.text %~ toUpper
in pure $ mkNode opts (PresentT xs) (show01 opts msg0 xs as) []
data ToTitle
instance (Show a, DTL.IsText a) => P ToTitle a where
type PP ToTitle a = a
eval _ opts as =
let msg0 = "ToTitle"
xs = toTitleAll (as ^. DTL.unpacked) ^. DTL.packed
in pure $ mkNode opts (PresentT xs) (show01 opts msg0 xs as) []
toTitleAll :: String -> String
toTitleAll (x:xs) = toUpper x : map toLower xs
toTitleAll [] = []
data Inits
instance ([a] ~ x, Show a) => P Inits x where
type PP Inits x = [x]
eval _ opts as =
let msg0 = "Inits"
xs = inits as
in pure $ mkNode opts (PresentT xs) (show01 opts msg0 xs as) []
data Tails
instance ([a] ~ x, Show a) => P Tails x where
type PP Tails x = [x]
eval _ opts as =
let msg0 = "Tails"
xs = tails as
in pure $ mkNode opts (PresentT xs) (show01 opts msg0 xs as) []
data Ones p
instance ( PP p x ~ [a]
, P p x
, Show a
) => P (Ones p) x where
type PP (Ones p) x = [PP p x]
eval _ opts x = do
let msg0 = "Ones"
pp <- eval (Proxy @p) opts x
pure $ case getValueLR opts msg0 pp [] of
Left e -> e
Right p ->
case chkSize opts msg0 p [hh pp] of
Left e -> e
Right () ->
let d = map pure p
in mkNode opts (PresentT d) (show01 opts msg0 d p) [hh pp]
data ShowP p
instance (Show (PP p x), P p x) => P (ShowP p) x where
type PP (ShowP p) x = String
eval _ opts x = do
let msg0 = "ShowP"
pp <- eval (Proxy @p) opts x
pure $ case getValueLR opts msg0 pp [] of
Left e -> e
Right p ->
let d = show p
in mkNode opts (PresentT d) (msg0 <> showLit0 opts " " d <> show1 opts " | " p) [hh pp]
data FormatTimeP p q
instance (PP p x ~ String
, FormatTime (PP q x)
, P p x
, Show (PP q x)
, P q x
) => P (FormatTimeP p q) x where
type PP (FormatTimeP p q) x = String
eval _ opts x = do
let msg0 = "FormatTimeP"
lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
pure $ case lr of
Left e -> e
Right (p,q,pp,qq) ->
let msg1 = msg0 <> " (" <> p <> ")"
b = formatTime defaultTimeLocale p q
in mkNode opts (PresentT b) (msg1 <> showLit0 opts " " b <> show1 opts " | " q) [hh pp, hh qq]
data ParseTimeP' t p q
instance (ParseTime (PP t a)
, Typeable (PP t a)
, Show (PP t a)
, P p a
, P q a
, PP p a ~ String
, PP q a ~ String
) => P (ParseTimeP' t p q) a where
type PP (ParseTimeP' t p q) a = PP t a
eval _ opts a = do
let msg0 = "ParseTimeP " <> t
t = showT @(PP t a)
lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts a []
pure $ case lr of
Left e -> e
Right (p,q,pp,qq) ->
let msg1 = msg0 <> " (" <> p <> ")"
hhs = [hh pp, hh qq]
in case parseTimeM @Maybe @(PP t a) True defaultTimeLocale p q of
Just b -> mkNode opts (PresentT b) (lit01' opts msg1 b "fmt=" p <> show1 opts " | " q) hhs
Nothing -> mkNode opts (FailT (msg1 <> " failed to parse")) (msg1 <> " failed") hhs
data ParseTimeP (t :: Type) p q
type ParseTimePT (t :: Type) p q = ParseTimeP' (Hole t) p q
instance P (ParseTimePT t p q) x => P (ParseTimeP t p q) x where
type PP (ParseTimeP t p q) x = PP (ParseTimePT t p q) x
eval _ = eval (Proxy @(ParseTimePT t p q))
data ParseTimes' t p q
instance (ParseTime (PP t a)
, Typeable (PP t a)
, Show (PP t a)
, P p a
, P q a
, PP p a ~ [String]
, PP q a ~ String
) => P (ParseTimes' t p q) a where
type PP (ParseTimes' t p q) a = PP t a
eval _ opts a = do
let msg0 = "ParseTimes " <> t
t = showT @(PP t a)
lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts a []
pure $ case lr of
Left e -> e
Right (p,q,pp,qq) ->
let msg1 = msg0
hhs = [hh pp, hh qq]
zs = map (\d -> (d,) <$> parseTimeM @Maybe @(PP t a) True defaultTimeLocale d q) p
in case catMaybes zs of
[] -> mkNode opts (FailT ("no match on [" ++ q ++ "]")) (msg1 <> " no match") hhs
(d,b):_ -> mkNode opts (PresentT b) (lit01' opts msg1 b "fmt=" d <> show1 opts " | " q) hhs
data ParseTimes (t :: Type) p q
type ParseTimesT (t :: Type) p q = ParseTimes' (Hole t) p q
instance P (ParseTimesT t p q) x => P (ParseTimes t p q) x where
type PP (ParseTimes t p q) x = PP (ParseTimesT t p q) x
eval _ = eval (Proxy @(ParseTimesT t p q))
data MkDay' p q r
instance (P p x
, P q x
, P r x
, PP p x ~ Int
, PP q x ~ Int
, PP r x ~ Int
) => P (MkDay' p q r) x where
type PP (MkDay' p q r) x = Maybe Day
eval _ opts x = do
let msg0 = "MkDay"
lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
case lr of
Left e -> pure e
Right (p,q,pp,qq) -> do
let hhs = [hh pp, hh qq]
rr <- eval (Proxy @r) opts x
pure $ case getValueLR opts msg0 rr hhs of
Left e -> e
Right r ->
let mday = fromGregorianValid (fromIntegral p) q r
in mkNode opts (PresentT mday) (show01' opts msg0 mday "(y,m,d)=" (p,q,r)) (hhs <> [hh rr])
data MkDay p
type MkDayT p = MkDay' (Fst p) (Snd p) (Thd p)
instance P (MkDayT p) x => P (MkDay p) x where
type PP (MkDay p) x = PP (MkDayT p) x
eval _ = eval (Proxy @(MkDayT p))
data UnMkDay p
instance (PP p x ~ Day, P p x) => P (UnMkDay p) x where
type PP (UnMkDay p) x = (Int, Int, Int)
eval _ opts x = do
let msg0 = "UnMkDay"
pp <- eval (Proxy @p) opts x
pure $ case getValueLR opts msg0 pp [] of
Left e -> e
Right p ->
let (fromIntegral -> y, m, d) = toGregorian p
b = (y, m, d)
in mkNode opts (PresentT b) (show01 opts msg0 b p) [hh pp]
data MkDayExtra' p q r
instance (P p x
, P q x
, P r x
, PP p x ~ Int
, PP q x ~ Int
, PP r x ~ Int
) => P (MkDayExtra' p q r) x where
type PP (MkDayExtra' p q r) x = Maybe (Day, Int, Int)
eval _ opts x = do
let msg0 = "MkDayExtra"
lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
case lr of
Left e -> pure e
Right (p,q,pp,qq) -> do
let hhs = [hh pp, hh qq]
rr <- eval (Proxy @r) opts x
pure $ case getValueLR opts msg0 rr hhs of
Left e -> e
Right r ->
let mday = fromGregorianValid (fromIntegral p) q r
b = mday <&> \day ->
let (_, week, dow) = toWeekDate day
in (day, week, dow)
in mkNode opts (PresentT b) (show01' opts msg0 b "(y,m,d)=" (p,q,r)) (hhs <> [hh rr])
data MkDayExtra p
type MkDayExtraT p = MkDayExtra' (Fst p) (Snd p) (Thd p)
instance P (MkDayExtraT p) x => P (MkDayExtra p) x where
type PP (MkDayExtra p) x = PP (MkDayExtraT p) x
eval _ = eval (Proxy @(MkDayExtraT p))
class ToDayC a where
getDay :: a -> Day
instance ToDayC UTCTime where
getDay = utctDay
instance ToDayC ZonedTime where
getDay = getDay . zonedTimeToLocalTime
instance ToDayC LocalTime where
getDay = localDay
instance ToDayC Day where
getDay = id
instance ToDayC Rational where
getDay = getDay . P.posixSecondsToUTCTime . fromRational
instance ToDayC CP.SystemTime where
getDay = getDay . CP.systemToUTCTime
class ToTimeC a where
getTime :: a -> TimeOfDay
instance ToTimeC UTCTime where
getTime = getTime . utctDayTime
instance ToTimeC ZonedTime where
getTime = getTime . zonedTimeToLocalTime
instance ToTimeC LocalTime where
getTime = localTimeOfDay
instance ToTimeC TimeOfDay where
getTime = id
instance ToTimeC DiffTime where
getTime = timeToTimeOfDay
instance ToTimeC Rational where
getTime = getTime . P.posixSecondsToUTCTime . fromRational
instance ToTimeC CP.SystemTime where
getTime = getTime . CP.systemToUTCTime
data ToDay p
instance (P p x, Show (PP p x), ToDayC (PP p x)) => P (ToDay p) x where
type PP (ToDay p) x = Day
eval _ opts x = do
let msg0 = "ToDay"
pp <- eval (Proxy @p) opts x
pure $ case getValueLR opts msg0 pp [] of
Left e -> e
Right p ->
let ret = getDay p
in mkNode opts (PresentT ret) (show01 opts msg0 ret p) [hh pp]
data ToTime p
instance ( P p x
, Show (PP p x)
, ToTimeC (PP p x)
) => P (ToTime p) x where
type PP (ToTime p) x = TimeOfDay
eval _ opts x = do
let msg0 = "ToTime"
pp <- eval (Proxy @p) opts x
pure $ case getValueLR opts msg0 pp [] of
Left e -> e
Right p ->
let ret = getTime p
in mkNode opts (PresentT ret) (show01 opts msg0 ret p) [hh pp]
data MkTime' p q r
instance (P p x
, P q x
, P r x
, PP p x ~ Int
, PP q x ~ Int
, PP r x ~ Rational
) => P (MkTime' p q r) x where
type PP (MkTime' p q r) x = TimeOfDay
eval _ opts x = do
let msg0 = "MkTime"
lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
case lr of
Left e -> pure e
Right (p,q,pp,qq) -> do
let hhs = [hh pp, hh qq]
rr <- eval (Proxy @r) opts x
pure $ case getValueLR opts msg0 rr hhs of
Left e -> e
Right r ->
let mtime = TimeOfDay p q (fromRational r)
in mkNode opts (PresentT mtime) (show01' opts msg0 mtime "(h,m,s)=" (p,q,r)) (hhs <> [hh rr])
data MkTime p
type MkTimeT p = MkTime' (Fst p) (Snd p) (Thd p)
instance P (MkTimeT p) x => P (MkTime p) x where
type PP (MkTime p) x = PP (MkTimeT p) x
eval _ = eval (Proxy @(MkTimeT p))
data UnMkTime p
instance (PP p x ~ TimeOfDay, P p x) => P (UnMkTime p) x where
type PP (UnMkTime p) x = (Int, Int, Rational)
eval _ opts x = do
let msg0 = "UnMkTime"
pp <- eval (Proxy @p) opts x
pure $ case getValueLR opts msg0 pp [] of
Left e -> e
Right p ->
let TimeOfDay h m s = p
b = (h, m, toRational s)
in mkNode opts (PresentT b) (show01 opts msg0 b p) [hh pp]
data PosixToUTCTime p
instance (PP p x ~ Rational, P p x) => P (PosixToUTCTime p) x where
type PP (PosixToUTCTime p) x = UTCTime
eval _ opts x = do
let msg0 = "PosixToUTCTime"
pp <- eval (Proxy @p) opts x
pure $ case getValueLR opts msg0 pp [] of
Left e -> e
Right p ->
let d = P.posixSecondsToUTCTime (fromRational p)
in mkNode opts (PresentT d) (show01 opts msg0 d p) [hh pp]
data UTCTimeToPosix p
instance (PP p x ~ UTCTime, P p x) => P (UTCTimeToPosix p) x where
type PP (UTCTimeToPosix p) x = Rational
eval _ opts x = do
let msg0 = "UTCTimeToPosix"
pp <- eval (Proxy @p) opts x
pure $ case getValueLR opts msg0 pp [] of
Left e -> e
Right p ->
let d = toRational $ P.utcTimeToPOSIXSeconds p
in mkNode opts (PresentT d) (show01 opts msg0 d p) [hh pp]
data ReadP' t p
instance (P p x
, PP p x ~ String
, Typeable (PP t x)
, Show (PP t x)
, Read (PP t x)
) => P (ReadP' t p) x where
type PP (ReadP' t p) x = PP t x
eval _ opts x = do
let msg0 = "ReadP " <> t
t = showT @(PP t x)
pp <- eval (Proxy @p) opts x
pure $ case getValueLR opts msg0 pp [] of
Left e -> e
Right s ->
let hhs = [hh pp]
in case reads @(PP t x) s of
[(b,"")] -> mkNode opts (PresentT b) (msg0 <> " " ++ show b) hhs
o -> mkNode opts (FailT (msg0 <> " (" ++ s ++ ")")) (msg0 <> " failed " <> show o <> " | s=" ++ s) hhs
data ReadP (t :: Type) p
type ReadPT (t :: Type) p = ReadP' (Hole t) p
instance P (ReadPT t p) x => P (ReadP t p) x where
type PP (ReadP t p) x = PP (ReadPT t p) x
eval _ = eval (Proxy @(ReadPT t p))
data ReadMaybe' t p
instance (P p x
, PP p x ~ String
, Typeable (PP t x)
, Show (PP t x)
, Read (PP t x)
) => P (ReadMaybe' t p) x where
type PP (ReadMaybe' t p) x = Maybe (PP t x, String)
eval _ opts x = do
let msg0 = "ReadMaybe " <> t
t = showT @(PP t x)
pp <- eval (Proxy @p) opts x
pure $ case getValueLR opts msg0 pp [] of
Left e -> e
Right s ->
let msg1 = msg0 <> " (" <> s <> ")"
hhs = [hh pp]
in case reads @(PP t x) s of
[(b,rest)] -> mkNode opts (PresentT (Just (b,rest))) (lit01 opts msg1 b s) hhs
o -> mkNode opts (PresentT Nothing) (msg1 <> " failed " <> show o) hhs
data ReadMaybe (t :: Type) p
type ReadMaybeT (t :: Type) p = ReadMaybe' (Hole t) p
instance P (ReadMaybeT t p) x => P (ReadMaybe t p) x where
type PP (ReadMaybe t p) x = PP (ReadMaybeT t p) x
eval _ = eval (Proxy @(ReadMaybeT t p))
data ReadQ' t p
type ReadQT' t p = ReadMaybe' t p >> MaybeIn (Failp "read failed") (Guard "oops" (Snd Id >> Null) >> Fst Id)
instance P (ReadQT' t p) x => P (ReadQ' t p) x where
type PP (ReadQ' t p) x = PP (ReadQT' t p) x
eval _ = eval (Proxy @(ReadQT' t p))
data ReadQ (t :: Type) p
type ReadQT (t :: Type) p = ReadQ' (Hole t) p
instance P (ReadQT t p) x => P (ReadQ t p) x where
type PP (ReadQ t p) x = PP (ReadQT t p) x
eval _ = eval (Proxy @(ReadQT t p))
data Sum
instance (Num a, Show a) => P Sum [a] where
type PP Sum [a] = a
eval _ opts as =
let msg0 = "Sum"
v = sum as
in pure $ mkNode opts (PresentT v) (show01 opts msg0 v as) []
data Product
instance (Num a, Show a) => P Product [a] where
type PP Product [a] = a
eval _ opts as =
let msg0 = "Product"
v = product as
in pure $ mkNode opts (PresentT v) (show01 opts msg0 v as) []
data Min
instance (Ord a, Show a) => P Min [a] where
type PP Min [a] = a
eval _ opts as' = do
let msg0 = "Min"
pure $ case as' of
[] -> mkNode opts (FailT "empty list") (msg0 <> "(empty list)") []
as@(_:_) ->
let v = minimum as
in mkNode opts (PresentT v) (show01 opts msg0 v as) []
data Max
instance (Ord a, Show a) => P Max [a] where
type PP Max [a] = a
eval _ opts as' = do
let msg0 = "Max"
pure $ case as' of
[] -> mkNode opts (FailT "empty list") (msg0 <> "(empty list)") []
as@(_:_) ->
let v = maximum as
in mkNode opts (PresentT v) (show01 opts msg0 v as) []
data SortBy p q
type SortByHelperT p = Partition (p == 'GT) Id
instance (P p (a,a)
, P q x
, Show a
, PP q x ~ [a]
, PP p (a,a) ~ Ordering
) => P (SortBy p q) x where
type PP (SortBy p q) x = PP q x
eval _ opts x = do
let msg0 = "SortBy"
qq <- eval (Proxy @q) opts x
case getValueLR opts (msg0 <> " q failed") qq [] of
Left e -> pure e
Right as -> do
let ff :: MonadEval m => [a] -> m (TT [a])
ff = \case
[] -> pure $ mkNode opts (PresentT mempty) (msg0 <> " empty") [hh qq]
[w] -> pure $ mkNode opts (PresentT [w]) (msg0 <> " one element " <> show w) [hh qq]
w:ys@(_:_) -> do
pp <- (if isVerbose opts then
eval (Proxy @(SortByHelperT p))
else eval (Proxy @(Hide (SortByHelperT p)))) opts (map (w,) ys)
case getValueLR opts msg0 pp [hh qq] of
Left e -> pure e
Right (ll', rr') -> do
lhs <- ff (map snd ll')
case getValueLR opts msg0 lhs [hh qq, hh pp] of
Left _ -> pure lhs
Right ll -> do
rhs <- ff (map snd rr')
case getValueLR opts msg0 rhs [hh qq, hh pp, hh lhs] of
Left _ -> pure rhs
Right rr ->
pure $ mkNode opts (PresentT (ll ++ w : rr))
(msg0 <> show0 opts " lhs=" ll <> " pivot " <> show w <> show0 opts " rhs=" rr)
(hh pp : [hh lhs | length ll > 1] ++ [hh rhs | length rr > 1])
ret <- ff as
pure $ case getValueLR opts msg0 ret [hh qq] of
Left _e -> ret
Right xs -> mkNode opts (_tBool ret) (msg0 <> show0 opts " " xs) [hh qq, hh ret]
data SortOn p q
type SortOnT p q = SortBy (OrdA p) q
instance P (SortOnT p q) x => P (SortOn p q) x where
type PP (SortOn p q) x = PP (SortOnT p q) x
eval _ = eval (Proxy @(SortOnT p q))
data SortOnDesc p q
type SortOnDescT p q = SortBy (Swap >> OrdA p) q
instance P (SortOnDescT p q) x => P (SortOnDesc p q) x where
type PP (SortOnDesc p q) x = PP (SortOnDescT p q) x
eval _ = eval (Proxy @(SortOnDescT p q))
data Len
instance (Show a, as ~ [a]) => P Len as where
type PP Len as = Int
eval _ opts as =
let msg0 = "Len"
n = length as
in pure $ mkNode opts (PresentT n) (show01 opts msg0 n as) []
data Length p
instance (PP p x ~ t a
, P p x
, Show (t a)
, Foldable t) => P (Length p) x where
type PP (Length p) x = Int
eval _ opts x = do
let msg0 = "Length"
pp <- eval (Proxy @p) opts x
pure $ case getValueLR opts msg0 pp [] of
Left e -> e
Right p ->
let n = length p
in mkNode opts (PresentT n) (show01 opts msg0 n p) [hh pp]
data Fst p
instance (Show (ExtractL1T (PP p x))
, ExtractL1C (PP p x)
, P p x
, Show (PP p x)
) => P (Fst p) x where
type PP (Fst p) x = ExtractL1T (PP p x)
eval _ opts x = do
let msg0 = "Fst"
pp <- eval (Proxy @p) opts x
pure $ case getValueLR opts msg0 pp [] of
Left e -> e
Right p ->
let b = extractL1C p
in mkNode opts (PresentT b) (show01 opts msg0 b p) [hh pp]
data L1 p
type L1T p = Fst p
instance P (L1T p) x => P (L1 p) x where
type PP (L1 p) x = PP (L1T p) x
eval _ = eval (Proxy @(L1T p))
class ExtractL1C tp where
type ExtractL1T tp
extractL1C :: tp -> ExtractL1T tp
instance ExtractL1C (a,b) where
type ExtractL1T (a,b) = a
extractL1C (a,_) = a
instance ExtractL1C (a,b,c) where
type ExtractL1T (a,b,c) = a
extractL1C (a,_,_) = a
instance ExtractL1C (a,b,c,d) where
type ExtractL1T (a,b,c,d) = a
extractL1C (a,_,_,_) = a
instance ExtractL1C (a,b,c,d,e) where
type ExtractL1T (a,b,c,d,e) = a
extractL1C (a,_,_,_,_) = a
instance ExtractL1C (a,b,c,d,e,f) where
type ExtractL1T (a,b,c,d,e,f) = a
extractL1C (a,_,_,_,_,_) = a
data Snd p
instance (Show (ExtractL2T (PP p x))
, ExtractL2C (PP p x)
, P p x
, Show (PP p x)
) => P (Snd p) x where
type PP (Snd p) x = ExtractL2T (PP p x)
eval _ opts x = do
let msg0 = "Snd"
pp <- eval (Proxy @p) opts x
pure $ case getValueLR opts msg0 pp [] of
Left e -> e
Right p ->
let b = extractL2C p
in mkNode opts (PresentT b) (show01 opts msg0 b p) [hh pp]
data L2 p
type L2T p = Snd p
instance P (L2T p) x => P (L2 p) x where
type PP (L2 p) x = PP (L2T p) x
eval _ = eval (Proxy @(L2T p))
class ExtractL2C tp where
type ExtractL2T tp
extractL2C :: tp -> ExtractL2T tp
instance ExtractL2C (a,b) where
type ExtractL2T (a,b) = b
extractL2C (_,b) = b
instance ExtractL2C (a,b,c) where
type ExtractL2T (a,b,c) = b
extractL2C (_,b,_) = b
instance ExtractL2C (a,b,c,d) where
type ExtractL2T (a,b,c,d) = b
extractL2C (_,b,_,_) = b
instance ExtractL2C (a,b,c,d,e) where
type ExtractL2T (a,b,c,d,e) = b
extractL2C (_,b,_,_,_) = b
instance ExtractL2C (a,b,c,d,e,f) where
type ExtractL2T (a,b,c,d,e,f) = b
extractL2C (_,b,_,_,_,_) = b
data Thd p
instance (Show (ExtractL3T (PP p x))
, ExtractL3C (PP p x)
, P p x
, Show (PP p x)
) => P (Thd p) x where
type PP (Thd p) x = ExtractL3T (PP p x)
eval _ opts x = do
let msg0 = "Thd"
pp <- eval (Proxy @p) opts x
pure $ case getValueLR opts msg0 pp [] of
Left e -> e
Right p ->
let b = extractL3C p
in mkNode opts (PresentT b) (show01 opts msg0 b p) [hh pp]
data L3 p
type L3T p = Thd p
instance P (L3T p) x => P (L3 p) x where
type PP (L3 p) x = PP (L3T p) x
eval _ = eval (Proxy @(L3T p))
class ExtractL3C tp where
type ExtractL3T tp
extractL3C :: tp -> ExtractL3T tp
instance ExtractL3C (a,b) where
type ExtractL3T (a,b) = GL.TypeError ('GL.Text "Thd doesn't work for 2-tuples")
extractL3C _ = errorInProgram "Thd doesn't work for 2-tuples"
instance ExtractL3C (a,b,c) where
type ExtractL3T (a,b,c) = c
extractL3C (_,_,c) = c
instance ExtractL3C (a,b,c,d) where
type ExtractL3T (a,b,c,d) = c
extractL3C (_,_,c,_) = c
instance ExtractL3C (a,b,c,d,e) where
type ExtractL3T (a,b,c,d,e) = c
extractL3C (_,_,c,_,_) = c
instance ExtractL3C (a,b,c,d,e,f) where
type ExtractL3T (a,b,c,d,e,f) = c
extractL3C (_,_,c,_,_,_) = c
data L4 p
instance (Show (ExtractL4T (PP p x))
, ExtractL4C (PP p x)
, P p x
, Show (PP p x)
) => P (L4 p) x where
type PP (L4 p) x = ExtractL4T (PP p x)
eval _ opts x = do
let msg0 = "L4"
pp <- eval (Proxy @p) opts x
pure $ case getValueLR opts msg0 pp [] of
Left e -> e
Right p ->
let b = extractL4C p
in mkNode opts (PresentT b) (show01 opts msg0 b p) [hh pp]
class ExtractL4C tp where
type ExtractL4T tp
extractL4C :: tp -> ExtractL4T tp
instance ExtractL4C (a,b) where
type ExtractL4T (a,b) = GL.TypeError ('GL.Text "L4 doesn't work for 2-tuples")
extractL4C _ = errorInProgram "L4 doesn't work for 2-tuples"
instance ExtractL4C (a,b,c) where
type ExtractL4T (a,b,c) = GL.TypeError ('GL.Text "L4 doesn't work for 3-tuples")
extractL4C _ = errorInProgram "L4 doesn't work for 3-tuples"
instance ExtractL4C (a,b,c,d) where
type ExtractL4T (a,b,c,d) = d
extractL4C (_,_,_,d) = d
instance ExtractL4C (a,b,c,d,e) where
type ExtractL4T (a,b,c,d,e) = d
extractL4C (_,_,_,d,_) = d
instance ExtractL4C (a,b,c,d,e,f) where
type ExtractL4T (a,b,c,d,e,f) = d
extractL4C (_,_,_,d,_,_) = d
data L5 p
instance (Show (ExtractL5T (PP p x))
, ExtractL5C (PP p x)
, P p x
, Show (PP p x)
) => P (L5 p) x where
type PP (L5 p) x = ExtractL5T (PP p x)
eval _ opts x = do
let msg0 = "L5"
pp <- eval (Proxy @p) opts x
pure $ case getValueLR opts msg0 pp [] of
Left e -> e
Right p ->
let b = extractL5C p
in mkNode opts (PresentT b) (show01 opts msg0 b p) [hh pp]
class ExtractL5C tp where
type ExtractL5T tp
extractL5C :: tp -> ExtractL5T tp
instance ExtractL5C (a,b) where
type ExtractL5T (a,b) = GL.TypeError ('GL.Text "L5 doesn't work for 2-tuples")
extractL5C _ = errorInProgram "L5 doesn't work for 2-tuples"
instance ExtractL5C (a,b,c) where
type ExtractL5T (a,b,c) = GL.TypeError ('GL.Text "L5 doesn't work for 3-tuples")
extractL5C _ = errorInProgram "L5 doesn't work for 3-tuples"
instance ExtractL5C (a,b,c,d) where
type ExtractL5T (a,b,c,d) = GL.TypeError ('GL.Text "L5 doesn't work for 4-tuples")
extractL5C _ = errorInProgram "L5 doesn't work for 4-tuples"
instance ExtractL5C (a,b,c,d,e) where
type ExtractL5T (a,b,c,d,e) = e
extractL5C (_,_,_,_,e) = e
instance ExtractL5C (a,b,c,d,e,f) where
type ExtractL5T (a,b,c,d,e,f) = e
extractL5C (_,_,_,_,e,_) = e
data L6 p
instance (Show (ExtractL6T (PP p x))
, ExtractL6C (PP p x)
, P p x
, Show (PP p x)
) => P (L6 p) x where
type PP (L6 p) x = ExtractL6T (PP p x)
eval _ opts x = do
let msg0 = "L6"
pp <- eval (Proxy @p) opts x
pure $ case getValueLR opts msg0 pp [] of
Left e -> e
Right p ->
let b = extractL6C p
in mkNode opts (PresentT