2015-06-19 61 views
0

我正在編寫這個小程序,基本上是爲了將每個輸入標記標識爲operator/parenthesis/int。Haskell中的Tokenizer標識符

不過,我遇到了一個問題,說明

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

對於Not in scope: data constructor 'Integer'一部分,問題是你在該行

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

有一個額外的Integer這應該是

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

[c]部分必需的,因爲已經readread :: Read a => String -> a鍵入,和cChar,但[c]是僅包含炭c一個String


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 ,那麼你應該刪除所有不正確的輸入

| otherwise = TError : (dropWhile (\o -> o == TError) (tokenize cs)) 
1

構建TNumber時,不需要(也不應該)包含每個構造函數參數的類型。因此,你需要改變這一點:

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

這樣:

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

我試圖擦除「整數」,現在我得到無法匹配預期的類型'字符串'推斷的類型'字符' – Walle