never executed always true always false
    1 {-# LANGUAGE GADTs      #-}
    2 {-# LANGUAGE RankNTypes #-}
    3 module HelVM.HelMA.Automaton.Eff.GADTEff
    4   ( GADTEff
    5   , GADTEffF (..)
    6   , interpretGADTEff
    7   , interpretGADTEffDebug
    8   ) where
    9 
   10 import           HelVM.HelMA.Automaton.Eff.MonadEff
   11 
   12 import           Control.Monad.Logger
   13 
   14 import           Prelude                            hiding ( getLine, putLTextLn, putText, putTextLn )
   15 
   16 newtype GADTEff a
   17   = GADTEff { runGADTEff :: forall m. Monad m => (forall x. GADTEffF x -> m x) -> m a }
   18 
   19 instance Functor GADTEff where
   20   fmap f m = GADTEff $ \k -> fmap f (runGADTEff m k)
   21 
   22 instance Applicative GADTEff where
   23   pure a  = GADTEff $ \_ -> pure a
   24   f <*> a = GADTEff $ \k -> runGADTEff f k <*> runGADTEff a k
   25 
   26 instance Monad GADTEff where
   27   return = pure
   28   m >>= f = GADTEff $ \k -> runGADTEff m k >>= \a -> runGADTEff (f a) k
   29 
   30 liftF ∷ GADTEffF a → GADTEff a
   31 liftF fa = GADTEff $ \k -> k fa
   32 
   33 --------------------------------------------------------------------------------
   34 -- Interpretacja
   35 
   36 interpretGADTEffDebug ∷ AppEff m ⇒ GADTEff a → m a
   37 interpretGADTEffDebug eff = runGADTEff eff interpretGADTEffFDebug
   38 
   39 interpretGADTEff ∷ MonadEff m ⇒ GADTEff a → m a
   40 interpretGADTEff eff = runGADTEff eff interpretGADTEffF
   41 
   42 --------------------------------------------------------------------------------
   43 -- Interpreter dla pojedynczych instrukcji (bez fmap/kontynuacji!)
   44 
   45 interpretGADTEffFDebug ∷ AppEff m ⇒ GADTEffF a → m a
   46 interpretGADTEffFDebug GetContentsBS   = logDebugN "GetContentsBS"   *> getContentsBS
   47 interpretGADTEffFDebug GetContentsText = logDebugN "GetContentsText" *> getContentsText
   48 interpretGADTEffFDebug GetChar         = logAndCont =<< getChar where logAndCont c = logDebugN ("GetChar: " <> one c) $> c
   49 interpretGADTEffFDebug GetLine         = logAndCont =<< getLine where logAndCont l = logDebugN ("GetLine: " <>     l) $> l
   50 interpretGADTEffFDebug (PutChar c)     = logDebugN ("PutChar: " <> one c) *> putChar c
   51 interpretGADTEffFDebug (PutText s)     = logDebugN ("PutText: " <>     s) *> putLine s
   52 interpretGADTEffFDebug Flush           = logDebugN "Flush"                *> flush
   53 
   54 interpretGADTEffF ∷ MonadEff m ⇒ GADTEffF a → m a
   55 interpretGADTEffF GetContentsBS   = getContentsBS
   56 interpretGADTEffF GetContentsText = getContentsText
   57 interpretGADTEffF GetChar         = getChar
   58 interpretGADTEffF GetLine         = getLine
   59 interpretGADTEffF (PutChar c)     = putChar c
   60 interpretGADTEffF (PutText s)     = putLine s
   61 interpretGADTEffF Flush           = flush
   62 
   63 --------------------------------------------------------------------------------
   64 
   65 instance MonadEff GADTEff where
   66   getContentsBS   = gadtGetContentsBS
   67   getContentsText = gadtGetContentsText
   68   getChar         = gadtGetChar
   69   getLine         = gadtGetLine
   70   putChar         = gadtPutChar
   71   putLine         = gadtPutLine
   72   flush           = gadtFlush
   73 
   74 gadtGetContentsBS ∷ GADTEff LByteString
   75 gadtGetContentsBS = liftF GetContentsBS
   76 
   77 gadtGetContentsText ∷ GADTEff LText
   78 gadtGetContentsText = liftF GetContentsText
   79 
   80 gadtGetChar ∷ GADTEff Char
   81 gadtGetChar = liftF GetChar
   82 
   83 gadtGetLine ∷ GADTEff Text
   84 gadtGetLine = liftF GetLine
   85 
   86 gadtPutChar ∷ Char → GADTEff ()
   87 gadtPutChar = liftF . PutChar
   88 
   89 gadtPutLine ∷ Text → GADTEff ()
   90 gadtPutLine = liftF . PutText
   91 
   92 gadtFlush ∷ GADTEff ()
   93 gadtFlush = liftF Flush
   94 
   95 --------------------------------------------------------------------------------
   96 
   97 data GADTEffF a where
   98   GetContentsBS :: GADTEffF LByteString
   99   GetContentsText :: GADTEffF LText
  100   GetChar :: GADTEffF Char
  101   GetLine :: GADTEffF Text
  102   PutChar :: Char -> GADTEffF ()
  103   PutText :: Text -> GADTEffF ()
  104   Flush :: GADTEffF ()