never executed always true always false
    1 {-# LANGUAGE GADTs      #-}
    2 {-# LANGUAGE RankNTypes #-}
    3 
    4 module HelVM.HelMA.Automaton.Eff.GADTEff (
    5   interpretGADTEffDebug,
    6   interpretGADTEff,
    7   GADTEff,
    8   GADTEffF(..),
    9 ) where
   10 
   11 import           HelVM.HelMA.Automaton.Eff.MonadEff
   12 
   13 import           Control.Monad.Logger
   14 
   15 import           Prelude                            hiding (getLine, putLTextLn, putText, putTextLn)
   16 
   17 newtype GADTEff a = 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 :: MonadLoggerEff 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 :: MonadLoggerEff 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 ()