Execute a Markov algorithm: Difference between revisions
→{{header|Haskell}}: Made the necessary improvements.
Underscore (talk | contribs) m (Placed the task description and test cases before the table of contents, as per convention. (IMO, this is a very useful convention; it ensures every top-level section in the ToC is an implementation.)) |
Underscore (talk | contribs) (→{{header|Haskell}}: Made the necessary improvements.) |
||
Line 162:
=={{header|Haskell}}==
This program expects a source file as an argument and uses the standard input and output devices for the algorithm's I/O.
<lang
import Data.Maybe (catMaybes)
import Control.Monad
import Text.ParserCombinators.Parsec
import System.IO
import System.Environment (getArgs)
main = do
args <- getArgs
unless (length args == 1) $
fail "Please provide exactly one source file as an argument."
let sourcePath = head args
source <- readFile sourcePath
input <- getContents
case parse markovParser sourcePath source of
Right rules -> putStrLn $ runMarkov rules input
Left err -> hPutStrLn stderr $ "Parse error at " ++ show err
data Rule = Rule
{from :: String, terminating :: Bool, to :: String}
"A -> apple",▼
algorithm :: Parser [Rule]▼
algorithm = liftM catMaybes $▼
(comment' <|> rule') `sepEndBy` (many1 newline)▼
where comment' = comment >> return Nothing▼
rule' = (liftM Just rule) <?> "rule"▼
(option False $ char '.' >> return True)▼
nonnl = noneOf "\n"▼
ws = many1 $ oneOf " \t"▼
(manyTill (nonnl <?> "pattern character") $ try arrow)
(succeeds $ char '.')
arrow = ws >> string "->" >> ws <?> "whitespace-delimited arrow"
▲ nonnl = noneOf "\n"
▲ ws = many1 $ oneOf " \t"
where f [] s = s
f
where g _ "" = f rs s
g before ahead@(a : as) = if from `isPrefixOf` ahead
then let new =
in if terminating then new else f rules new
else g (a : before) as</lang>
|