I'm not quite sure what you are trying to do with lexers, and am knowledgeable enough to guide you about it (but if all you need is useless filter tokens, alex monadic interface seems redundant), anyway here is a sample code for use AlexUserState to accumulate selected tokens using the monadUserState shell.
{ module Main (main) where } %wrapper "monadUserState" $digit = 0-9 -- digits $alpha = [a-zA-Z] -- alphabetic characters $dbl_quote = \" tokens :- $white+ ; "," { ignoreToken } ">" { ignoreToken } $dbl_quote [^$dbl_quote]* $dbl_quote { pushToken $ ErlStr . init . tail } $digit+ { pushToken $ ErlInt . read } { alexEOF :: Alex () alexEOF = return () -- some useful interaces to the Alex monad (which is naturally an instance of state monad) modifyUserState :: (AlexUserState -> AlexUserState) -> Alex () modifyUserState f = Alex (\s -> let st = alex_ust s in Right (s {alex_ust = f st},())) getUserState :: Alex AlexUserState getUserState = Alex (\s -> Right (s,alex_ust s)) -- Token definition minus position information for simplicity data Token = Comma | BinaryOpen | BinaryClose | ErlInt Integer | ErlStr String deriving (Eq, Show) newtype AlexUserState = Binary [Token] deriving (Eq, Show) alexInitUserState :: AlexUserState alexInitUserState = Binary [] -- action helpers: pushToken :: (String -> Token) -> AlexAction () pushToken tokenizer = \(posn,prevChar,pending,s) len -> modifyUserState (push $ take len s) >> alexMonadScan where -- Here tokens are accumulated in reverse order for efficiency. -- You need a more powerful data structure like Data.Sequence to preserve the order. push :: String -> AlexUserState -> AlexUserState push s (Binary ts) = Binary (tokenizer s : ts) ignoreToken :: AlexAction () ignoreToken _ _ = alexMonadScan runAlexScan :: String -> Either String AlexUserState runAlexScan s = runAlex s $ alexMonadScan >> getUserState main :: IO () main = getContents >>= print . runAlexScan }
But I guess the main problem is that you don't seem to be familiar enough with the concept and use of monads in Haskell yet. The monadic interface of Alex is actually very natural and typical of state monads, and as soon as you have some coding experience, this is something you can easily guess by simply compiling the generated code. (And in case you guessed that type checking is likely to find the corresponding error.)
For this, since there seem to be a lot of good questions and answers about monads, I just refer to Real World Haskell (whose chapter on profiling was especially useful to me.)
But if you already have some knowledge of category theory, perhaps the fastest way to learn monads is to immerse yourself in some relevant documents directly (and please remember that the monad in category theory is a generalization of actions as in the action of groups that fit naturally into the programming context.) For this, see this list of articles on monads and arrows , which includes introductory articles and tutorials for people with specific technical experience.
By the way, I just started to study Erlang. Could you tell me a little about this? Don't you have static typing? Have you tried cloud-haskell and compared it to Erlang? And in what language do you consider yourself the most productive in the context of distributed programming?
mnish
source share