data Pos = NoPos | Pos Int Int | Eof deriving (Eq,Ord,Show,Read ) lexical :: String -> [(Pos,Str ing )] lexical i = lex' 1 1 i where lex' r c [] = [] lex' r c xxs@('\n': xs) = lex' (r+1) 1 xs lex' r c xxs@(x:xs) = if isSpace x then lex' r (c+1) xs else if isDigit x then token r c (span isDigit xxs) else if isAlpha x then token r c (span isAlpha xxs) else (Pos r c,[x]) : lex' r (c+1) xs token r c (t,xs) = (Pos r c,t) : lex' r (c+length t) xs This is a lexical analyser that transforms a list of characters into a list of position-tokens pairs. Positions contain row and column numbers of the token, unless it is the end of file which has its own constructor. The NoPos and Eof positions are not used by the lexical analyser itself, the parsers use them if they reach an unexpected end of the tok en list or do not know where the error is. The input string is transformed from a list of characters to a a list of strings, where each string is a lexical tok en. The tokens are paired with their positions to make it possible to report positions of errors in the input.