module
Test.Chuchu.Types
(ChuchuParser (..), Chuchu, ChuchuM (Given, When, Then, And, But), runChuchu)
where
import Control.Applicative hiding ((<|>))
import Data.String
import Text.Parsec
import Text.Parsec.Text
newtype ChuchuParser a
= ChuchuParser (Parser a) deriving (Functor, Applicative, Monad)
instance (a ~ ()) => IsString (ChuchuParser a) where
fromString s = ChuchuParser (string s >> return ())
type Chuchu m = ChuchuM m ()
data ChuchuM m a where
Given :: ChuchuParser a -> (a -> m ()) -> ChuchuM m ()
When :: ChuchuParser a -> (a -> m ()) -> ChuchuM m ()
Then :: ChuchuParser a -> (a -> m ()) -> ChuchuM m ()
And :: ChuchuParser a -> (a -> m ()) -> ChuchuM m ()
But :: ChuchuParser a -> (a -> m ()) -> ChuchuM m ()
Nil :: ChuchuM m a
Cons :: ChuchuM m b -> ChuchuM m a -> ChuchuM m a
instance Monad (ChuchuM m) where
return _ = Nil
step >>= k = Cons step $ k $ error "(>>=): ChuchuM does not support 'return'."
runChuchu :: ChuchuM m a -> Parser (m ())
runChuchu Nil = unexpected "Unknown step"
runChuchu (Cons cc1 cc2) = runChuchu cc1 <|> runChuchu cc2
runChuchu (Given p f) = apply p f
runChuchu (When p f) = apply p f
runChuchu (Then p f) = apply p f
runChuchu (And p f) = apply p f
runChuchu (But p f) = apply p f
apply :: ChuchuParser a -> (a -> m ()) -> Parser (m ())
apply (ChuchuParser p) f = try $ f <$> p <* eof