Initial query AST
This commit is contained in:
36
src/Data/Functor/Foldable.hs
Normal file
36
src/Data/Functor/Foldable.hs
Normal file
@ -0,0 +1,36 @@
|
||||
{-|
|
||||
Module : Data.Functor.Foldable
|
||||
Description : Simplified recursion schemes
|
||||
Copyright : (c) Mats Rauhala, 2020
|
||||
License : BSD-3-Clause
|
||||
Maintainer : mats.rauhala@iki.fi
|
||||
Stability : experimental
|
||||
Portability : POSIX
|
||||
|
||||
Simplified recursion schemes, providing only the minimal schemes
|
||||
-}
|
||||
module Data.Functor.Foldable
|
||||
( Fix(..)
|
||||
, cata
|
||||
, ana
|
||||
, hylo
|
||||
)
|
||||
where
|
||||
|
||||
newtype Fix f = Fix { getFix :: f (Fix f) }
|
||||
|
||||
-- | Catamorphism or the fold
|
||||
--
|
||||
-- Fold a recursive structure into a value
|
||||
cata :: Functor f => (f a -> a) -> Fix f -> a
|
||||
cata f = a where a = f . fmap a . getFix
|
||||
|
||||
-- | Anamorphism or the unfold
|
||||
--
|
||||
-- Unfold a seed into a recursive structure
|
||||
ana :: Functor f => (a -> f a) -> a -> Fix f
|
||||
ana f = a where a = Fix . fmap a . f
|
||||
|
||||
-- | Combined fold and unfold
|
||||
hylo :: (Functor f) => (f a -> a) -> (b -> f b) -> b -> a
|
||||
hylo f u = a where a = f . fmap a . u
|
52
src/Data/Query.hs
Normal file
52
src/Data/Query.hs
Normal file
@ -0,0 +1,52 @@
|
||||
{-# LANGUAGE GADTs #-}
|
||||
{-# LANGUAGE LambdaCase #-}
|
||||
module Data.Query
|
||||
(
|
||||
-- * Combinators
|
||||
startsWith
|
||||
, endsWith
|
||||
, (.&&.)
|
||||
|
||||
-- * Evaluating queries
|
||||
, evaluate
|
||||
)
|
||||
where
|
||||
|
||||
import Data.Buuka
|
||||
(BuukaEntry(..), URL(..))
|
||||
|
||||
import Data.List
|
||||
(isPrefixOf, isSuffixOf)
|
||||
|
||||
import Data.Functor.Foldable
|
||||
(Fix(..))
|
||||
|
||||
data Field a where
|
||||
Url :: Field String
|
||||
Title :: Field String
|
||||
|
||||
data QueryF f
|
||||
= forall a. StartsWith (Field a) a
|
||||
| forall a. EndsWith (Field a) a
|
||||
| And f f
|
||||
|
||||
deriving instance Functor QueryF
|
||||
|
||||
type Query = Fix QueryF
|
||||
|
||||
startsWith :: Field a -> a -> Query
|
||||
startsWith field x = Fix (StartsWith field x)
|
||||
|
||||
endsWith :: Field a -> a -> Query
|
||||
endsWith field x = Fix (EndsWith field x)
|
||||
|
||||
(.&&.) :: Query -> Query -> Query
|
||||
a .&&. b = Fix (And a b)
|
||||
|
||||
evaluate :: QueryF (BuukaEntry -> Bool) -> (BuukaEntry -> Bool)
|
||||
evaluate = \case
|
||||
StartsWith Url x -> \BuukaEntry{url=URL u} -> x `isPrefixOf` u
|
||||
EndsWith Url x -> \BuukaEntry{url=URL u} -> x `isSuffixOf` u
|
||||
StartsWith Title x -> \BuukaEntry{title=t} -> maybe False (x `isPrefixOf`) t
|
||||
EndsWith Title x -> \BuukaEntry{title=t} -> maybe False (x `isSuffixOf`) t
|
||||
And a b -> \e -> a e && b e
|
Reference in New Issue
Block a user