Haskell中的Tokenizer标识符

时间:2015-06-19 20:14:26

标签: haskell

我正在编写这个小程序,主要是将每个输入标记识别为operator / parenthesis / int。

但是,我遇到了一个问题,说明

Not in scope: data constructor `Integer'

这是我到目前为止(Data.Char仅定义isDigit,没有别的)

import Data.Char (isDigit)
data Token = TPlus | TTimes | TParenLeft | TParenRight | TNumber Integer | TError
    deriving (Show, Eq)


tokenize :: String -> [Token]
tokenize [] = []
tokenize (c:cs)
    | c == '+' = TPlus : tokenize cs
    | c == '*' = TTimes : tokenize cs
    | c == '(' = TParenLeft : tokenize cs
    | c == ')' = TParenRight : tokenize cs
    | isDigit c = TNumber Integer (read c) : tokenize cs
    | otherwise = TError : tokenize cs

一些预期输出示例:

*Main> tokenize "( 1 + 2 )"

应该给出

[TParenLeft,TNumber 1,TPlus,TNumber 2,TParenRight]

*Main> tokenize "abc"

应该期待TError,但我得到

[TError,TError,TError]

如果有人能对这两个问题有所了解,我感激不尽。

2 个答案:

答案 0 :(得分:2)

对于Not in scope: data constructor 'Integer'部分,问题是您在行中有额外的Integer

isDigit c = TNumber Integer (read c) : tokenize cs

应该是

isDigit c = TNumber (read [c]) : tokenize cs

需要[c]部分,因为read的类型为read :: Read a => String -> acChar,但[c]为{{} 1}}只包含char String

由于您的错误处理政策,

c正在返回tokenize "abc"

[TError, TError, TError]

这导致我们:

| otherwise = TError : tokenize cs

如果您想将所有错误归为一个tokenize "abc" -- c = 'a', cs = "bc" TError : tokenize "bc" TError : (TError : tokenize "c") TError : TError : TError : [] [TError, TError, TError] ,那么您应该删除所有错误的输入

TError

答案 1 :(得分:1)

构建TNumber时,您不需要(也不应该)包含每个构造函数参数的类型。因此,您需要更改此内容:

| isDigit c = TNumber Integer (read c) : tokenize cs

到此:

| isDigit c = TNumber (read c) : tokenize cs