我正在编写这个小程序,主要是将每个输入标记识别为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]
如果有人能对这两个问题有所了解,我感激不尽。
答案 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 -> a
,c
为Char
,但[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