Haskell:if-then-else解析错误

Jef*_*eff 0 parsing haskell if-statement

我正在研究Read ComplexInt的一个实例.

这是给出的:

data ComplexInt = ComplexInt Int Int
deriving (Show)
Run Code Online (Sandbox Code Playgroud)

module Parser (Parser,parser,runParser,satisfy,char,string,many,many1,(+++)) where

import Data.Char
import Control.Monad
import Control.Monad.State

type Parser = StateT String []

runParser :: Parser a -> String -> [(a,String)]
runParser = runStateT

parser :: (String -> [(a,String)]) -> Parser a
parser = StateT

satisfy :: (Char -> Bool) -> Parser Char
satisfy f = parser $ \s -> case s of
    [] -> []
    a:as -> [(a,as) | f a]

char :: Char -> Parser Char
char = satisfy . (==)

alpha,digit :: Parser Char
alpha = satisfy isAlpha
digit = satisfy isDigit

string :: String -> Parser String
string = mapM char

infixr 5 +++
(+++) :: Parser a -> Parser a -> Parser a
(+++) = mplus

many, many1 :: Parser a -> Parser [a]
many p = return [] +++ many1 p
many1 p = liftM2 (:) p (many p)
Run Code Online (Sandbox Code Playgroud)

这是给定的练习:

"Use Parser to implement Read ComplexInt, where you can accept either the simple integer 
syntax "12" for ComplexInt 12 0 or "(1,2)" for ComplexInt 1 2, and illustrate that read 
works as expected (when its return type is specialized appropriately) on these examples. 
Don't worry (yet) about the possibility of minus signs in the specification of natural 
numbers."
Run Code Online (Sandbox Code Playgroud)

这是我的尝试:

data ComplexInt = ComplexInt Int Int
    deriving (Show)

instance Read ComplexInt where
    readsPrec _ = runParser parseComplexInt

parseComplexInt :: Parser ComplexInt
parseComplexInt = do
    statestring <- getContents
    case statestring of
        if '(' `elem` statestring 
            then do process1 statestring
            else do process2 statestring
    where
    process1 ststr = do
        number <- read(dropWhile (not(isDigit)) ststr) :: Int
        return ComplexInt number 0
    process2 ststr = do
        numbers <- dropWhile (not(isDigit)) ststr
        number1 <- read(takeWhile (not(isSpace)) numbers) :: Int
        number2 <- read(dropWhile (not(isSpace)) numbers) :: Int
        return ComplexInt number1 number2
Run Code Online (Sandbox Code Playgroud)

这是我的错误(我当前的错误,因为我确定一旦我排除了这个错误就会有更多错误,但我会在时间上采取这一步):

Parse error in pattern: if ')' `elem` statestring then
                            do { process1 statestring }
                        else
                            do { process2 statestring }
Run Code Online (Sandbox Code Playgroud)

我基于if-then-else语句的结构基于此问题中使用的结构:在Haskell中解析输入错误if-then-else条件

如果您发现任何明显错误,我将非常感谢if-then-else块以及一般代码的任何帮助.

jwo*_*der 6

让我们看看解析错误周围的代码.

case statestring of
    if '(' `elem` statestring 
        then do process1 statestring
        else do process2 statestring
Run Code Online (Sandbox Code Playgroud)

那不是多么case有效.它应该像这样使用:

case statestring of
    "foo"  ->  -- code for when statestring == "foo"
    'b':xs ->  -- code for when statestring begins with 'b'
    _      ->  -- code for none of the above
Run Code Online (Sandbox Code Playgroud)

既然你没有对它进行任何实际的使用,那就完全case摆脱它case.

(而且,由于他们只后跟单个语句中的每个,在do后小号thenelse都是多余的.)