1

parsec ライブラリを使用して haskell で文法を実装しようとしていますが、予想される Vs に問題があります。文法で定義されている実際の型、私は私の質問への答えが間違いなく単純/明白であることを知っていますが、残念ながら私が理解していないことがあります...

データ宣言の抜粋は次のとおりです (診断には十分なはずです)。

data Expr1 = SeqOfExpr1 [Expr1]
            | Lambda Expr8 Expr1
            | List Expr2 Expr1
            | If Expr2 Expr1 Expr1
            | Expr2
              deriving (Show)

data Expr2 =  SeqOfExpr3 [Expr3]
              deriving (Show)

data Expr3 =  SeqOfExpr4 [Expr4]
              deriving (Show)
 ----------------------------Redundant Code Omitted------------------------------
expr1 :: Parser Expr1   
expr1 = declaration
      <|> list
      <|> ifStmt
      <|> expr2

declaration :: Parser Expr1
declaration =
    do  reservedOp "\\"
        var <- name
        reservedOp "->"
        expr <- expr1
        return $ Lambda var expr

list :: Parser Expr1    
list =
    do exprA <- expr2
       reservedOp ":"
       exprB <- expr1
       return $ List exprA exprB

現在、Expr8 までの式のデータ宣言がありますが、それらは expr2 -> expr3 とほとんど同じです。それらの間の違いは、それらがどのように区切られているかです。たとえば、Expr3 は「||」で区切られ、Expr4 は「&&」で区切られています。

私が抱えている問題の1つ(解決された場合、残りを修正するアイデアが得られるはずです):

List 値コンストラクターは、競合の原因となる Expr1 を返します。

Couldn't match expected type `Expr2' with actual type `Expr1'
In the first argument of `List', namely `exprA'
In the second argument of `($)', namely `List exprA exprB'
In a stmt of a 'do' block: return $ List exprA exprB

Expr2 を Expr1 の値宣言として使用しているためだと思いますが、この問題を解決するために文法を修正する方法がわかりません。

助けてくれてありがとう!

ショーン

4

1 に答える 1

5

にはdata Expr1、nullary コンストラクターがありExpr2ます。あなたはそれが次のようなことを意味していたと思います

data Expr1 =
           ...
           | Foo Expr2

をラップしExpr2ます。

とにかく、その通り

expr1 :: Parser Expr1   
expr1 = declaration
      <|> list
      <|> ifStmt
      <|> expr2

コンパイラは を推論expr2 :: Parser Expr1しますが、試してみると

list :: Parser Expr1    
list =
    do exprA <- expr2
       reservedOp ":"
       exprB <- expr1
       return $ List exprA exprB

Listmeansの型はでexprAなければなりませんが、Expr2expr2型から、コンパイラは を認識しexprA :: Expr1ます。

expr2したがって、おそらくラップする必要がありますlist

list = ...
     <|> fmap Foo expr2

の定義を変更しExpr1てコンストラクタを含め、Fooをラップする場合Expr2

于 2013-03-15T16:00:17.620 に答える