3

次のコードがあります。

parseExpr :: [String] -> (Ast,[String])
parseExpr [] = error "Incorrect"
parseExpr (s:ss) | all isDigit s = (Tall (read s),ss)
              | s == "-" = let (e,ss') = parseExpr ss in (Min e,ss')
              | s == "+" = (Sum e e',ss'') where
                           (e,ss') = parseExpr ss
                           (e',ss'') = parseExpr ss'
              | s == "*" = (Mult e e',ss'') where
                           (e,ss') = parseExpr ss
                           (e',ss'') = parseExpr ss'

実行しようとすると、「入力 '|' の解析エラー」というエラーが表示されます。それが話している行は次のとおりです。

...
                           (e',ss'') = parseExpr ss'
->            | s == "*" = (Mult e e',ss'') where
                           (e,ss') = parseExpr ss
...

理由はわかると思います。ガードによってシールドされていない上に 2 つの線があり、下に別のガードが突然現れると、Haskell が混乱するためだと思います。しかし、これらのケースの後にガードを追加するにはどうすればよいでしょうか?

新しい行を区切るためにセミコロンを使用しようとしましたが、Haskell を初めて使用するため、その構文についてあまり知りません。

4

1 に答える 1

2

中括弧を使用する必要はありません(もちろん使用できます)。ただし、インデントには注意が必要です。最初に見えるほど難しくはありません。

whereそうは言っても、保護された式の中で使用できないのは事実です。letこのような場合は、次のように使用する必要があります。

parseExpr :: [String] -> (Ast,[String])
parseExpr [] = error "Incorrect"
parseExpr (s:ss) | all isDigit s = (Tall (read s),ss)
              | s == "-" = let (e,ss') = parseExpr ss in (Min e,ss')
              | s == "+" = let (e,ss') = parseExpr ss
                               (e',ss'') = parseExpr ss'
                           in (Sum e e',ss'')
              | s == "*" = let (e,ss') = parseExpr ss
                               (e',ss'') = parseExpr ss'
                           in (Mult e e',ss'')

ただし、ここでのケースでは、ガード式は非常に単純であるため、パターン マッチに置き換えることができます。(この機会を利用することをお勧めします。パターン マッチングは Haskell の親友です。)その場合は、 を使用しますwhere

parseExpr :: [String] -> (Ast,[String])
parseExpr [] = error "Incorrect"
parseExpr (s:ss) | all isDigit s = (Tall (read s),ss)
parseExpr ("-":ss) = (Min e,ss') where (e,ss') = parseExpr ss
parseExpr ("+":ss) = (Sum  e e',ss'') where (e, ss' ) = parseExpr ss
                                            (e',ss'') = parseExpr ss'

parseExpr ("*":ss) = (Mult e e',ss'') where (e, ss' ) = parseExpr ss
                                            (e',ss'') = parseExpr ss'
于 2019-10-10T17:09:19.930 に答える