This is the extra file.
Created
August 19, 2014 10:00
-
-
Save mpickering/f74e1f5cbd15084c6ea8 to your computer and use it in GitHub Desktop.
Transclusion
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE DeriveFunctor #-} | |
import Control.Monad.Free | |
import Text.Parsec hiding ((<|>), many) | |
import Control.Applicative | |
import Control.Monad.Trans | |
-- All impure effects are abstracted to a data type, it can be extended as | |
-- new impure effects are needed. | |
data ImpureF a = ReadFile FilePath (String -> a) deriving Functor | |
type Impure = Free ImpureF | |
include :: FilePath -> Impure String | |
include fp = liftF $ ReadFile fp id | |
-- If running in IO, we can perform impure effects | |
run :: Impure a -> IO a | |
run (Pure r) = return r | |
run (Free (ReadFile fp f)) = readFile fp >>= run . f | |
-- If in a pure setting we can't process includes | |
runPure :: Impure a -> a | |
runPure (Pure r) = r | |
runPure (Free (ReadFile _ f)) = runPure $ f "" | |
md = "This is a markdown file with an \n {extrafile.md} which should be inserted in the middle" | |
data AST = Word String deriving (Show) | |
-- We place the impure free monad at the bottom of the stack | |
mdparser :: ParsecT String () Impure [AST] | |
mdparser = many (try includemd <|> word) | |
includemd = do | |
char '{' | |
fname <- manyTill anyChar (char '}') | |
conts <- lift $ include fname | |
return (Word conts) | |
word = Word <$> (spaces *> (many1 (noneOf " ")) <* spaces) | |
getRight (Right x) = x | |
main :: IO () | |
main = do | |
let inp = runParserT mdparser () "" md | |
putStrLn "pure" | |
putStrLn . show $ getRight (runPure inp) | |
putStrLn "impure" | |
putStrLn . show . getRight =<< run inp | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment