Lexer for expression evaluator
No need of TokenType: data Token = Identifier String | RealNumberLiteral String | PlusSign ...
No need of nested let statements, see http://learnyouahaskell.com/syntax-in-functions#let-it-be
camelCase naming is preferred everywhere.
generally it is more efficient to aggregate lists using cons (: operator), and reverse at the end, if needed. It is about tokens ++ [next_token] fragment.
read_token could return a tuple of token and the rest string, no need to drop (length next_token_lexeme) source_code after that.


Note, I didn't inspect code logic at all.