{-# LANGUAGE KindSignatures #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE NoMonomorphismRestriction #-} module Control.Monad.Apiary.Filter.Internal.Strategy where import Data.Apiary.SList import Data.Maybe import Data.Proxy import Data.Reflection class Strategy (w :: * -> *) where type SNext w (as :: [*]) a :: [*] readStrategy :: (v -> Maybe a) -> ((k,v) -> Bool) -> Proxy (w a) -> [(k, v)] -> SList as -> Maybe (SList (SNext w as a)) getQuery :: (v -> Maybe a) -> Proxy (w a) -> ((k,v) -> Bool) -> [(k, v)] -> [Maybe a] getQuery readf _ kf = map readf . map snd . filter kf -- | get first matched key( [1,) params to Type.). since 0.5.0.0. data Option a instance Strategy Option where type SNext Option as a = Snoc as (Maybe a) readStrategy rf k p q l = let rs = getQuery rf p k q in if any isNothing rs then Nothing else Just . sSnoc l $ case catMaybes rs of [] -> Nothing a:_ -> Just a -- | get first matched key ( [0,) params to Maybe Type.) since 0.5.0.0. data First a instance Strategy First where type SNext First as a = Snoc as a readStrategy rf k p q l = let rs = getQuery rf p k q in if any isNothing rs then Nothing else case catMaybes rs of [] -> Nothing a:_ -> Just $ sSnoc l a -- | get key ( [1] param to Type.) since 0.5.0.0. data One a instance Strategy One where type SNext One as a = Snoc as a readStrategy rf k p q l = let rs = getQuery rf p k q in if any isNothing rs then Nothing else case catMaybes rs of [a] -> Just $ sSnoc l a _ -> Nothing -- | get parameters ( [0,) params to [Type] ) since 0.5.0.0. data Many a instance Strategy Many where type SNext Many as a = Snoc as [a] readStrategy rf k p q l = let rs = getQuery rf p k q in if any isNothing rs then Nothing else Just $ sSnoc l (catMaybes rs) -- | get parameters ( [1,) params to [Type] ) since 0.5.0.0. data Some a instance Strategy Some where type SNext Some as a = Snoc as [a] readStrategy rf k p q l = let rs = getQuery rf p k q in if any isNothing rs then Nothing else case catMaybes rs of [] -> Nothing as -> Just $ sSnoc l as -- | get parameters with upper limit ( [1,n] to [Type]) since 0.6.0.0. data LimitSome u a instance (Reifies u Int) => Strategy (LimitSome u) where type SNext (LimitSome u) as a = Snoc as [a] readStrategy rf k p q l = let rs = take (reflectLimit p) $ getQuery rf p k q in if any isNothing rs then Nothing else case catMaybes rs of [] -> Nothing as -> Just $ sSnoc l as reflectLimit :: Reifies n Int => Proxy (LimitSome n a) -> Int reflectLimit p = reflect $ asTyInt p where asTyInt :: Proxy (LimitSome u a) -> Proxy u asTyInt _ = Proxy -- | type check ( [0,) params to No argument ) since 0.5.0.0. data Check a instance Strategy Check where type SNext Check as a = as readStrategy rf k p q l = let rs = getQuery rf p k q in if any isNothing rs then Nothing else case catMaybes rs of [] -> Nothing _ -> Just l -- | construct Option proxy. since 0.5.1.0. pOption :: Proxy a -> Proxy (Option a) pOption _ = Proxy -- | construct First proxy. since 0.5.1.0. pFirst :: Proxy a -> Proxy (First a) pFirst _ = Proxy -- | construct One proxy. since 0.5.1.0. pOne :: Proxy a -> Proxy (One a) pOne _ = Proxy -- | construct Many proxy. since 0.5.1.0. pMany :: Proxy a -> Proxy (Many a) pMany _ = Proxy -- | construct Some proxy. since 0.5.1.0. pSome :: Proxy a -> Proxy (Some a) pSome _ = Proxy -- | construct Check proxy. since 0.5.1.0. pCheck :: Proxy a -> Proxy (Check a) pCheck _ = Proxy