Использование одной из библиотек анализатора Haskell может сделать такие вещи менее болезненными и подверженными ошибкам. Вот пример того, как это сделать с Attoparsec :
module Main where
import Control.Applicative
import qualified Data.Map as M
import Data.Attoparsec (maybeResult)
import qualified Data.Attoparsec.Char8 as A
import qualified Data.ByteString.Char8 as B
type Environment = M.Map String String
spaces = A.many $ A.char ' '
upTo delimiter = B.unpack <$> A.takeWhile (A.notInClass $ delimiter : " ")
<* (spaces >> A.char delimiter >> spaces)
entry = (,) <$> upTo ':' <*> upTo ';'
environment :: A.Parser Environment
environment = M.fromList <$> A.sepBy entry A.endOfLine
parseEnvironment :: B.ByteString -> Maybe Environment
parseEnvironment = maybeResult . flip A.feed B.empty . A.parse environment
Если у нас есть файл context.txt
:
user: somebody;
home: somewhere;
x: 1;
y: 2;
z: 3;
Мы можем проверить синтаксический анализатор следующим образом:
*Main> Just env <- parseEnvironment <$> B.readFile "context.txt"
*Main> print $ M.lookup "user" env
Just "somebody"
*Main> print env
fromList [("home","somewhere"),("user","somebody"),("x","1"),("y","2"),("z","3")]
Обратите внимание, что я использую Map
для представления окружения, как предложил camcann в комментарии к вашему предыдущему Reader
вопросу о монаде.