{-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GADTs #-} module Data.Foscam.File.Alias( Alias(..) , AsAlias(..) , AsAliasHead(..) , AsAliasTail(..) , alias ) where import Control.Applicative(Applicative((<*>)), (<$>)) import Control.Category(Category(id)) import Control.Lens(Optic', Choice, Cons(_Cons), prism', lens, (^?), (#)) import Control.Monad(Monad) import Data.Eq(Eq) import Data.Foscam.File.AliasCharacter(AliasCharacter, AsAliasCharacter(_AliasCharacter), aliasCharacter) import Data.Functor(Functor) import Data.Maybe(Maybe(Nothing, Just)) import Data.Ord(Ord) import Data.String(String) import Data.Traversable(traverse) import Prelude(Show) import Text.Parser.Char(CharParsing) import Text.Parser.Combinators(many, (), try) -- $setup -- >>> import Text.Parsec data Alias = Alias AliasCharacter [AliasCharacter] deriving (Eq, Ord, Show) class AsAlias p f s where _Alias :: Optic' p f s Alias instance AsAlias p f Alias where _Alias = id instance (Choice p, Applicative f) => AsAlias p f String where _Alias = prism' (\(Alias h t) -> (_AliasCharacter #) <$> (h:t)) (\s -> case s of [] -> Nothing h:t -> let ch = (^? _AliasCharacter) in Alias <$> ch h <*> traverse ch t) instance Cons Alias Alias AliasCharacter AliasCharacter where _Cons = prism' (\(h, Alias h' t) -> Alias h (h':t)) (\(Alias h t) -> case t of [] -> Nothing u:v -> Just (h, Alias u v)) class AsAliasHead p f s where _AliasHead :: Optic' p f s AliasCharacter instance AsAliasHead p f AliasCharacter where _AliasHead = id instance (p ~ (->), Functor f) => AsAliasHead p f Alias where _AliasHead = lens (\(Alias h _) -> h) (\(Alias _ t) h -> Alias h t) class AsAliasTail p f s where _AliasTail :: Optic' p f s [AliasCharacter] instance AsAliasTail p f [AliasCharacter] where _AliasTail = id instance (p ~ (->), Functor f) => AsAliasTail p f Alias where _AliasTail = lens (\(Alias _ t) -> t) (\(Alias h _) t -> Alias h t) -- | -- -- >>> parse alias "test" "abcdef" -- Right (Alias (AliasCharacter 'a') [AliasCharacter 'b',AliasCharacter 'c',AliasCharacter 'd',AliasCharacter 'e',AliasCharacter 'f']) -- -- >>> parse alias "test" "abc123" -- Right (Alias (AliasCharacter 'a') [AliasCharacter 'b',AliasCharacter 'c',AliasCharacter '1',AliasCharacter '2',AliasCharacter '3']) -- -- >>> parse alias "test" "abc*123" -- Right (Alias (AliasCharacter 'a') [AliasCharacter 'b',AliasCharacter 'c']) -- -- >>> parse alias "test" "abc*" -- Right (Alias (AliasCharacter 'a') [AliasCharacter 'b',AliasCharacter 'c']) -- -- >>> parse alias "test" "" -- Left "test" (line 1, column 1): -- unexpected end of input -- expecting alias alias :: (Monad f, CharParsing f) => f Alias alias = let a = try aliasCharacter in Alias <$> a <*> many a "alias"