a x || x == '_' =
    let (ident, rest) = span (\x -> isAlphaNum x || x == '_') xs
    in case ident of
        "true" -> BoolConst True : lexer rest
        "false" -> BoolConst False : lexer rest
        "while" -> WhileKeyword : lexer rest
        "if" -> IfKeyword : lexer rest
        "then" -> ThenKeyword : lexer rest
        "else" -> ElseKeyword : lexer rest
        "not" -> NotKeyword : lexer rest
        _ -> Ident ident : lexer rest
lexer xs@(x:_) | isDig
lexer xs@(x:_) | isAlpha x || x == '_' =
    let (ident, rest) = span (\x -> isAlphaNum x || x == '_') xs
    in case ident of
        "true" -> BoolConst True : lexer rest
        "false" -> BoolConst False : lexer rest
        "while" -> WhileKeyword : lexer rest
        "if" -> IfKeyword : lexer rest
        "then" -> ThenKeyword : lexer rest
        "else" -> ElseKeyword : lexer rest
        "not" -> NotKeyword : lexer rest
        _ -> Ident ident : lexer rest
lexer xs@(x:_) | isAlpha x || x == '_' =
    let (ident, rest) = span (\x -> isAlphaNum x || x == '_') xs
    in case ident of
        "true" -> BoolConst True : lexer rest
        "false" -> BoolConst False : lexer rest
        "while" -> WhileKeyword : lexer rest
        "if" -> IfKeyword : lexer rest
        "then" -> ThenKeyword : lexer rest
        "else" -> ElseKeyword : lexer rest
        "not" -> NotKeyword : lexer rest
        _ -> Ident ident : lexer rest