module Futhark.Profile.SourceRange (SourceRange (..), startLineCol, endLineCol, filter123, overlapsWith, mergeSemigroup, parse, fileName) where
import Control.Arrow ((&&&))
import Control.Monad (void, when)
import Data.Bifunctor (first)
import Data.Loc (Pos (Pos), posCol, posFile, posLine)
import Data.Text qualified as T
import Data.Void (Void)
import Text.Megaparsec qualified as P
import Text.Megaparsec.Char.Lexer qualified as L
data SourceRange = SourceRange
{ SourceRange -> Pos
startPos :: !Pos,
SourceRange -> Int
endLine :: !Int,
SourceRange -> Int
endColumn :: !Int
}
deriving (Int -> SourceRange -> ShowS
[SourceRange] -> ShowS
SourceRange -> String
(Int -> SourceRange -> ShowS)
-> (SourceRange -> String)
-> ([SourceRange] -> ShowS)
-> Show SourceRange
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> SourceRange -> ShowS
showsPrec :: Int -> SourceRange -> ShowS
$cshow :: SourceRange -> String
show :: SourceRange -> String
$cshowList :: [SourceRange] -> ShowS
showList :: [SourceRange] -> ShowS
Show, SourceRange -> SourceRange -> Bool
(SourceRange -> SourceRange -> Bool)
-> (SourceRange -> SourceRange -> Bool) -> Eq SourceRange
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: SourceRange -> SourceRange -> Bool
== :: SourceRange -> SourceRange -> Bool
$c/= :: SourceRange -> SourceRange -> Bool
/= :: SourceRange -> SourceRange -> Bool
Eq, Eq SourceRange
Eq SourceRange =>
(SourceRange -> SourceRange -> Ordering)
-> (SourceRange -> SourceRange -> Bool)
-> (SourceRange -> SourceRange -> Bool)
-> (SourceRange -> SourceRange -> Bool)
-> (SourceRange -> SourceRange -> Bool)
-> (SourceRange -> SourceRange -> SourceRange)
-> (SourceRange -> SourceRange -> SourceRange)
-> Ord SourceRange
SourceRange -> SourceRange -> Bool
SourceRange -> SourceRange -> Ordering
SourceRange -> SourceRange -> SourceRange
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: SourceRange -> SourceRange -> Ordering
compare :: SourceRange -> SourceRange -> Ordering
$c< :: SourceRange -> SourceRange -> Bool
< :: SourceRange -> SourceRange -> Bool
$c<= :: SourceRange -> SourceRange -> Bool
<= :: SourceRange -> SourceRange -> Bool
$c> :: SourceRange -> SourceRange -> Bool
> :: SourceRange -> SourceRange -> Bool
$c>= :: SourceRange -> SourceRange -> Bool
>= :: SourceRange -> SourceRange -> Bool
$cmax :: SourceRange -> SourceRange -> SourceRange
max :: SourceRange -> SourceRange -> SourceRange
$cmin :: SourceRange -> SourceRange -> SourceRange
min :: SourceRange -> SourceRange -> SourceRange
Ord)
fileName :: SourceRange -> FilePath
fileName :: SourceRange -> String
fileName = Pos -> String
posFile (Pos -> String) -> (SourceRange -> Pos) -> SourceRange -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SourceRange -> Pos
startPos
startLineCol :: SourceRange -> (Int, Int)
startLineCol :: SourceRange -> (Int, Int)
startLineCol (SourceRange Pos
pos Int
_ Int
_) = (Pos -> Int
posLine Pos
pos, Pos -> Int
posCol Pos
pos)
endLineCol :: SourceRange -> (Int, Int)
endLineCol :: SourceRange -> (Int, Int)
endLineCol (SourceRange Pos
_ Int
line Int
col) = (Int
line, Int
col)
overlapsWith :: SourceRange -> SourceRange -> Bool
overlapsWith :: SourceRange -> SourceRange -> Bool
overlapsWith SourceRange
a SourceRange
b =
let rangeOverlaps :: (a, a) -> (a, a) -> Bool
rangeOverlaps (a
sa, a
ea) (a
sb, a
eb) = a
sa a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
eb Bool -> Bool -> Bool
&& a
sb a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
ea
startA :: (Int, Int)
startA = SourceRange -> (Int, Int)
startLineCol SourceRange
a
endA :: (Int, Int)
endA = SourceRange -> (Int, Int)
endLineCol SourceRange
a
startB :: (Int, Int)
startB = SourceRange -> (Int, Int)
startLineCol SourceRange
b
endB :: (Int, Int)
endB = SourceRange -> (Int, Int)
endLineCol SourceRange
b
in ((Int, Int), (Int, Int)) -> ((Int, Int), (Int, Int)) -> Bool
forall {a} {a}. (Ord a, Ord a) => (a, a) -> (a, a) -> Bool
rangeOverlaps ((Int, Int)
startA, (Int, Int)
endA) ((Int, Int)
startB, (Int, Int)
endB)
isEmpty :: SourceRange -> Bool
isEmpty :: SourceRange -> Bool
isEmpty (SourceRange (Pos String
_ Int
startLine Int
startCol Int
_) Int
endLine Int
endCol) =
Int
startLine Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
endLine Bool -> Bool -> Bool
&& Int
startCol Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
endCol
parse :: T.Text -> Either T.Text SourceRange
parse :: Text -> Either Text SourceRange
parse Text
text = (ParseErrorBundle Text Void -> Text)
-> Either (ParseErrorBundle Text Void) SourceRange
-> Either Text SourceRange
forall a b c. (a -> b) -> Either a c -> Either b c
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first ParseErrorBundle Text Void -> Text
textErrorBundle (Either (ParseErrorBundle Text Void) SourceRange
-> Either Text SourceRange)
-> Either (ParseErrorBundle Text Void) SourceRange
-> Either Text SourceRange
forall a b. (a -> b) -> a -> b
$ Parsec Void Text SourceRange
-> String
-> Text
-> Either (ParseErrorBundle Text Void) SourceRange
forall e s a.
Parsec e s a -> String -> s -> Either (ParseErrorBundle s e) a
P.parse Parsec Void Text SourceRange
pSourceRange String
fname Text
text
where
fname :: String
fname = String
""
textErrorBundle :: ParseErrorBundle Text Void -> Text
textErrorBundle = String -> Text
T.pack (String -> Text)
-> (ParseErrorBundle Text Void -> String)
-> ParseErrorBundle Text Void
-> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParseErrorBundle Text Void -> String
forall s e.
(VisualStream s, TraversableStream s, ShowErrorComponent e) =>
ParseErrorBundle s e -> String
P.errorBundlePretty
lineRangeInvariantMessage :: String
lineRangeInvariantMessage =
String
"End of Line Range is not bigger than or equal to Start of Line Range."
columnRangeInvariantMessage :: String
columnRangeInvariantMessage =
String
"End of Column Range is not bigger than or equal to Start of Column Range"
pSourceRange :: P.Parsec Void T.Text SourceRange
pSourceRange :: Parsec Void Text SourceRange
pSourceRange = do
filePath <- ParsecT Void Text Identity Char
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m Char
L.charLiteral ParsecT Void Text Identity Char
-> ParsecT Void Text Identity (Token Text)
-> ParsecT Void Text Identity String
forall (m :: * -> *) a end. MonadPlus m => m a -> m end -> m [a]
`P.manyTill` Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
MonadParsec e s m =>
Token s -> m (Token s)
P.single Char
Token Text
':'
startLine <- L.decimal
void $ P.single ':'
startCol <- L.decimal
void $ P.single '-'
rangeEnd1 <- L.decimal
(lineRangeEnd, columnRangeEnd) <-
P.choice
[ do
endCol <- P.single ':' *> L.decimal
pure (rangeEnd1, endCol),
pure (startLine, rangeEnd1)
]
let lineRangeInvalid = Int
startLine Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
lineRangeEnd
when lineRangeInvalid $ fail lineRangeInvariantMessage
let columnRangeInvalid =
Int
startLine Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
lineRangeEnd Bool -> Bool -> Bool
&& Int
startCol Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
columnRangeEnd
when columnRangeInvalid $ fail columnRangeInvariantMessage
pure $
SourceRange
{ startPos = Pos filePath startLine startCol (-1),
endLine = lineRangeEnd,
endColumn = columnRangeEnd
}
mergeSemigroup ::
(Semigroup s) =>
(SourceRange, s) ->
(SourceRange, s) ->
OneTwoThree (SourceRange, s)
mergeSemigroup :: forall s.
Semigroup s =>
(SourceRange, s)
-> (SourceRange, s) -> OneTwoThree (SourceRange, s)
mergeSemigroup a :: (SourceRange, s)
a@(SourceRange
rangeA, s
auxA) b :: (SourceRange, s)
b@(SourceRange
rangeB, s
auxB) =
let orderedBy :: (b -> a) -> b -> b -> (b, b)
orderedBy b -> a
f b
x b
y = if b -> a
f b
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< b -> a
f b
y then (b
x, b
y) else (b
y, b
x)
((SourceRange, s)
startsEarlier, (SourceRange, s)
startsLater) = ((SourceRange, s) -> (Int, Int))
-> (SourceRange, s)
-> (SourceRange, s)
-> ((SourceRange, s), (SourceRange, s))
forall {a} {b}. Ord a => (b -> a) -> b -> b -> (b, b)
orderedBy (SourceRange -> (Int, Int)
startLineCol (SourceRange -> (Int, Int))
-> ((SourceRange, s) -> SourceRange)
-> (SourceRange, s)
-> (Int, Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (SourceRange, s) -> SourceRange
forall a b. (a, b) -> a
fst) (SourceRange, s)
a (SourceRange, s)
b
startsLaterStart :: (Int, Int)
startsLaterStart = SourceRange -> (Int, Int)
startLineCol (SourceRange -> (Int, Int))
-> ((SourceRange, s) -> SourceRange)
-> (SourceRange, s)
-> (Int, Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (SourceRange, s) -> SourceRange
forall a b. (a, b) -> a
fst ((SourceRange, s) -> (Int, Int)) -> (SourceRange, s) -> (Int, Int)
forall a b. (a -> b) -> a -> b
$ (SourceRange, s)
startsLater
fname :: String
fname = Pos -> String
posFile (Pos -> String) -> (SourceRange -> Pos) -> SourceRange -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SourceRange -> Pos
startPos (SourceRange -> String) -> SourceRange -> String
forall a b. (a -> b) -> a -> b
$ SourceRange
rangeA
((SourceRange, s)
endsEarlier, (SourceRange, s)
endsLater) =
((SourceRange, s) -> (Int, Int))
-> (SourceRange, s)
-> (SourceRange, s)
-> ((SourceRange, s), (SourceRange, s))
forall {a} {b}. Ord a => (b -> a) -> b -> b -> (b, b)
orderedBy
((SourceRange -> Int
endLine (SourceRange -> Int)
-> (SourceRange -> Int) -> SourceRange -> (Int, Int)
forall b c c'. (b -> c) -> (b -> c') -> b -> (c, c')
forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& SourceRange -> Int
endColumn) (SourceRange -> (Int, Int))
-> ((SourceRange, s) -> SourceRange)
-> (SourceRange, s)
-> (Int, Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (SourceRange, s) -> SourceRange
forall a b. (a, b) -> a
fst)
(SourceRange, s)
a
(SourceRange, s)
b
firstRange :: SourceRange
firstRange =
((SourceRange, s) -> SourceRange
forall a b. (a, b) -> a
fst (SourceRange, s)
startsEarlier)
{ endLine = fst startsLaterStart,
endColumn = snd startsLaterStart
}
secondRange :: SourceRange
secondRange =
((SourceRange, s) -> SourceRange
forall a b. (a, b) -> a
fst (SourceRange, s)
startsLater)
{ endLine = endLine . fst $ endsEarlier,
endColumn = endColumn . fst $ endsEarlier
}
thirdRange :: SourceRange
thirdRange =
let startLine :: Int
startLine = SourceRange -> Int
endLine SourceRange
secondRange
startCol :: Int
startCol = SourceRange -> Int
endColumn SourceRange
secondRange
in ((SourceRange, s) -> SourceRange
forall a b. (a, b) -> a
fst (SourceRange, s)
endsLater)
{ startPos = Pos fname startLine startCol (-1)
}
rawRanges :: OneTwoThree (SourceRange, s)
rawRanges =
(SourceRange, s)
-> (SourceRange, s)
-> (SourceRange, s)
-> OneTwoThree (SourceRange, s)
forall a. a -> a -> a -> OneTwoThree a
Three
(SourceRange
firstRange, (SourceRange, s) -> s
forall a b. (a, b) -> b
snd (SourceRange, s)
startsEarlier)
(SourceRange
secondRange, s
auxA s -> s -> s
forall a. Semigroup a => a -> a -> a
<> s
auxB)
(SourceRange
thirdRange, (SourceRange, s) -> s
forall a b. (a, b) -> b
snd (SourceRange, s)
endsLater)
in case ((SourceRange, s) -> Bool)
-> OneTwoThree (SourceRange, s)
-> Maybe (OneTwoThree (SourceRange, s))
forall a. (a -> Bool) -> OneTwoThree a -> Maybe (OneTwoThree a)
filter123 (Bool -> Bool
not (Bool -> Bool)
-> ((SourceRange, s) -> Bool) -> (SourceRange, s) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SourceRange -> Bool
isEmpty (SourceRange -> Bool)
-> ((SourceRange, s) -> SourceRange) -> (SourceRange, s) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (SourceRange, s) -> SourceRange
forall a b. (a, b) -> a
fst) OneTwoThree (SourceRange, s)
rawRanges of
Maybe (OneTwoThree (SourceRange, s))
Nothing ->
String -> OneTwoThree (SourceRange, s)
forall a. HasCallStack => String -> a
error (String -> OneTwoThree (SourceRange, s))
-> ([String] -> String) -> [String] -> OneTwoThree (SourceRange, s)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> String
unwords ([String] -> OneTwoThree (SourceRange, s))
-> [String] -> OneTwoThree (SourceRange, s)
forall a b. (a -> b) -> a -> b
$
[ String
"Impossible! `mergeRanges` produced no range at all, input ranges:",
SourceRange -> String
forall a. Show a => a -> String
show SourceRange
rangeA,
SourceRange -> String
forall a. Show a => a -> String
show SourceRange
rangeB
]
Just OneTwoThree (SourceRange, s)
merged -> OneTwoThree (SourceRange, s)
merged
data OneTwoThree a = One a | Two a a | Three a a a
deriving (Int -> OneTwoThree a -> ShowS
[OneTwoThree a] -> ShowS
OneTwoThree a -> String
(Int -> OneTwoThree a -> ShowS)
-> (OneTwoThree a -> String)
-> ([OneTwoThree a] -> ShowS)
-> Show (OneTwoThree a)
forall a. Show a => Int -> OneTwoThree a -> ShowS
forall a. Show a => [OneTwoThree a] -> ShowS
forall a. Show a => OneTwoThree a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> OneTwoThree a -> ShowS
showsPrec :: Int -> OneTwoThree a -> ShowS
$cshow :: forall a. Show a => OneTwoThree a -> String
show :: OneTwoThree a -> String
$cshowList :: forall a. Show a => [OneTwoThree a] -> ShowS
showList :: [OneTwoThree a] -> ShowS
Show, (forall a b. (a -> b) -> OneTwoThree a -> OneTwoThree b)
-> (forall a b. a -> OneTwoThree b -> OneTwoThree a)
-> Functor OneTwoThree
forall a b. a -> OneTwoThree b -> OneTwoThree a
forall a b. (a -> b) -> OneTwoThree a -> OneTwoThree b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall a b. (a -> b) -> OneTwoThree a -> OneTwoThree b
fmap :: forall a b. (a -> b) -> OneTwoThree a -> OneTwoThree b
$c<$ :: forall a b. a -> OneTwoThree b -> OneTwoThree a
<$ :: forall a b. a -> OneTwoThree b -> OneTwoThree a
Functor, (forall m. Monoid m => OneTwoThree m -> m)
-> (forall m a. Monoid m => (a -> m) -> OneTwoThree a -> m)
-> (forall m a. Monoid m => (a -> m) -> OneTwoThree a -> m)
-> (forall a b. (a -> b -> b) -> b -> OneTwoThree a -> b)
-> (forall a b. (a -> b -> b) -> b -> OneTwoThree a -> b)
-> (forall b a. (b -> a -> b) -> b -> OneTwoThree a -> b)
-> (forall b a. (b -> a -> b) -> b -> OneTwoThree a -> b)
-> (forall a. (a -> a -> a) -> OneTwoThree a -> a)
-> (forall a. (a -> a -> a) -> OneTwoThree a -> a)
-> (forall a. OneTwoThree a -> [a])
-> (forall a. OneTwoThree a -> Bool)
-> (forall a. OneTwoThree a -> Int)
-> (forall a. Eq a => a -> OneTwoThree a -> Bool)
-> (forall a. Ord a => OneTwoThree a -> a)
-> (forall a. Ord a => OneTwoThree a -> a)
-> (forall a. Num a => OneTwoThree a -> a)
-> (forall a. Num a => OneTwoThree a -> a)
-> Foldable OneTwoThree
forall a. Eq a => a -> OneTwoThree a -> Bool
forall a. Num a => OneTwoThree a -> a
forall a. Ord a => OneTwoThree a -> a
forall m. Monoid m => OneTwoThree m -> m
forall a. OneTwoThree a -> Bool
forall a. OneTwoThree a -> Int
forall a. OneTwoThree a -> [a]
forall a. (a -> a -> a) -> OneTwoThree a -> a
forall m a. Monoid m => (a -> m) -> OneTwoThree a -> m
forall b a. (b -> a -> b) -> b -> OneTwoThree a -> b
forall a b. (a -> b -> b) -> b -> OneTwoThree a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
$cfold :: forall m. Monoid m => OneTwoThree m -> m
fold :: forall m. Monoid m => OneTwoThree m -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> OneTwoThree a -> m
foldMap :: forall m a. Monoid m => (a -> m) -> OneTwoThree a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> OneTwoThree a -> m
foldMap' :: forall m a. Monoid m => (a -> m) -> OneTwoThree a -> m
$cfoldr :: forall a b. (a -> b -> b) -> b -> OneTwoThree a -> b
foldr :: forall a b. (a -> b -> b) -> b -> OneTwoThree a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> OneTwoThree a -> b
foldr' :: forall a b. (a -> b -> b) -> b -> OneTwoThree a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> OneTwoThree a -> b
foldl :: forall b a. (b -> a -> b) -> b -> OneTwoThree a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> OneTwoThree a -> b
foldl' :: forall b a. (b -> a -> b) -> b -> OneTwoThree a -> b
$cfoldr1 :: forall a. (a -> a -> a) -> OneTwoThree a -> a
foldr1 :: forall a. (a -> a -> a) -> OneTwoThree a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> OneTwoThree a -> a
foldl1 :: forall a. (a -> a -> a) -> OneTwoThree a -> a
$ctoList :: forall a. OneTwoThree a -> [a]
toList :: forall a. OneTwoThree a -> [a]
$cnull :: forall a. OneTwoThree a -> Bool
null :: forall a. OneTwoThree a -> Bool
$clength :: forall a. OneTwoThree a -> Int
length :: forall a. OneTwoThree a -> Int
$celem :: forall a. Eq a => a -> OneTwoThree a -> Bool
elem :: forall a. Eq a => a -> OneTwoThree a -> Bool
$cmaximum :: forall a. Ord a => OneTwoThree a -> a
maximum :: forall a. Ord a => OneTwoThree a -> a
$cminimum :: forall a. Ord a => OneTwoThree a -> a
minimum :: forall a. Ord a => OneTwoThree a -> a
$csum :: forall a. Num a => OneTwoThree a -> a
sum :: forall a. Num a => OneTwoThree a -> a
$cproduct :: forall a. Num a => OneTwoThree a -> a
product :: forall a. Num a => OneTwoThree a -> a
Foldable)
filter123 :: (a -> Bool) -> OneTwoThree a -> Maybe (OneTwoThree a)
filter123 :: forall a. (a -> Bool) -> OneTwoThree a -> Maybe (OneTwoThree a)
filter123 a -> Bool
p self :: OneTwoThree a
self@(One a
x) = if a -> Bool
p a
x then OneTwoThree a -> Maybe (OneTwoThree a)
forall a. a -> Maybe a
Just OneTwoThree a
self else Maybe (OneTwoThree a)
forall a. Maybe a
Nothing
filter123 a -> Bool
p self :: OneTwoThree a
self@(Two a
x a
y) = case (a -> Bool
p a
x, a -> Bool
p a
y) of
(Bool
True, Bool
True) -> OneTwoThree a -> Maybe (OneTwoThree a)
forall a. a -> Maybe a
Just OneTwoThree a
self
(Bool
True, Bool
False) -> OneTwoThree a -> Maybe (OneTwoThree a)
forall a. a -> Maybe a
Just (a -> OneTwoThree a
forall a. a -> OneTwoThree a
One a
x)
(Bool
False, Bool
True) -> OneTwoThree a -> Maybe (OneTwoThree a)
forall a. a -> Maybe a
Just (a -> OneTwoThree a
forall a. a -> OneTwoThree a
One a
y)
(Bool
False, Bool
False) -> Maybe (OneTwoThree a)
forall a. Maybe a
Nothing
filter123 a -> Bool
p self :: OneTwoThree a
self@(Three a
x a
y a
z) = case (a -> Bool
p a
x, a -> Bool
p a
y, a -> Bool
p a
z) of
(Bool
False, Bool
False, Bool
False) -> Maybe (OneTwoThree a)
forall a. Maybe a
Nothing
(Bool
False, Bool
False, Bool
True) -> OneTwoThree a -> Maybe (OneTwoThree a)
forall a. a -> Maybe a
Just (a -> OneTwoThree a
forall a. a -> OneTwoThree a
One a
z)
(Bool
False, Bool
True, Bool
False) -> OneTwoThree a -> Maybe (OneTwoThree a)
forall a. a -> Maybe a
Just (a -> OneTwoThree a
forall a. a -> OneTwoThree a
One a
y)
(Bool
False, Bool
True, Bool
True) -> OneTwoThree a -> Maybe (OneTwoThree a)
forall a. a -> Maybe a
Just (a -> a -> OneTwoThree a
forall a. a -> a -> OneTwoThree a
Two a
y a
z)
(Bool
True, Bool
False, Bool
False) -> OneTwoThree a -> Maybe (OneTwoThree a)
forall a. a -> Maybe a
Just (a -> OneTwoThree a
forall a. a -> OneTwoThree a
One a
x)
(Bool
True, Bool
False, Bool
True) -> OneTwoThree a -> Maybe (OneTwoThree a)
forall a. a -> Maybe a
Just (a -> a -> OneTwoThree a
forall a. a -> a -> OneTwoThree a
Two a
x a
z)
(Bool
True, Bool
True, Bool
False) -> OneTwoThree a -> Maybe (OneTwoThree a)
forall a. a -> Maybe a
Just (a -> a -> OneTwoThree a
forall a. a -> a -> OneTwoThree a
Two a
x a
y)
(Bool
True, Bool
True, Bool
True) -> OneTwoThree a -> Maybe (OneTwoThree a)
forall a. a -> Maybe a
Just OneTwoThree a
self