module ContextFilter (filterContext) where
filterContext ::
Int ->
Int ->
(a -> Bool) ->
[a] ->
[a]
filterContext :: forall a. Int -> Int -> (a -> Bool) -> [a] -> [a]
filterContext Int
before Int
after a -> Bool
p [a]
xs0
| Int
before forall a. Ord a => a -> a -> Bool
< Int
0 = forall a. HasCallStack => [Char] -> a
error [Char]
"filterContext: bad before"
| Int
after forall a. Ord a => a -> a -> Bool
< Int
0 = forall a. HasCallStack => [Char] -> a
error [Char]
"filterContext: bad after"
| Bool
otherwise = forall {a}. Int -> Int -> [a] -> [a] -> [a]
go Int
0 Int
0 [a]
xs0 [a]
xs0
where
width :: Int
width = Int
before forall a. Num a => a -> a -> a
+ Int
after
go :: Int -> Int -> [a] -> [a] -> [a]
go Int
i Int
m (a
x:[a]
xs) yys :: [a]
yys@(a
y:[a]
ys) =
if (Int
m forall a. Ord a => a -> a -> Bool
> Int
0 Bool -> Bool -> Bool
|| Bool
px) Bool -> Bool -> Bool
&& Int
i forall a. Ord a => a -> a -> Bool
>= Int
before then a
y forall a. a -> [a] -> [a]
: [a]
rest else [a]
rest
where
rest :: [a]
rest = Int -> Int -> [a] -> [a] -> [a]
go (Int
iforall a. Num a => a -> a -> a
+Int
1) Int
m' [a]
xs [a]
ys'
px :: Bool
px = a -> Bool
p a
x
m' :: Int
m' = forall a. Ord a => a -> a -> a
max (Int
mforall a. Num a => a -> a -> a
-Int
1) (if Bool
px then Int
width else Int
0)
ys' :: [a]
ys' = if Int
i forall a. Ord a => a -> a -> Bool
>= Int
before then [a]
ys else [a]
yys
go Int
_ Int
m [a]
_ [a]
ys = forall a. Int -> [a] -> [a]
take Int
m [a]
ys