1

私は haskell に非常に慣れていないので、このドキュメントhttps://www.cs.nott.ac.uk/~gmh/pearl.pdfで Monadic パーサーを作成するために使用される方法論を理解しようとしています。

正確に従うのではなく、正しく理解するために少し異なる方法で実行しようとしているため、最終的にこのコードになりました

newtype Parser a = Parser (String -> Maybe (a, String))

item :: Parser Char
item = Parser (\cs -> case cs of
            "" -> Nothing
            (c:cs) -> Just (c, cs))

getParser (Parser x) = x

instance Monad Parser where
    return x = Parser (\cs -> Just (x,cs))
    (Parser p) >>= f  = Parser (\cs -> let result = p cs in
                  case result of
                    Nothing -> Nothing
                    Just (c,cs') -> getParser (f c) cs')

takeThreeDropSecond :: Parser (Char, Char)
takeThreeDropSecond = do
    c1 <- item
    item
    c2 <- item
    return (c1, c2)

これは機能しているように見えますが、do 表記で何が起こっているのかを理解するのに苦労しています。

例えば; ではc1 <- item、何に割り当てられていc1ますか? 型に含まれているのは関数Parserですか、その計算の結果ですか、それとも他に何ですか? さらに、do 表記の 2 行目は justitemなので、実行するだけでitem結果を代入しないのですか? 最後に、何return (c1,c2)を生成しますか? それですか、Parser (String -> Maybe ((c1, c2)), String)それともただJust (c1, c2)ですか?

4

1 に答える 1

6

この型は、1) を使用して失敗を表し、2) 解析されなかった残りのテキストと、3) 解析された値(何でもかまいません) を返すParserことができる関数をラップします。モナドインスタンスは、それらを結び付ける配管です。実装は、1) 何かで成功する、2) 入力テキストを変更しない、3) 与えられた値を直接渡す関数の周りに を作成します。実装はパーサーと関数を取り、最初に を実行して作成された新しいパーサーを返し、次にその結果が の実行に合格したか失敗したかに基づいて作成されます。Maybe(a, String)areturnParserJust>>=pf

ではtakeThreeDropSecond、最初にc1 <- item「与えられたを を使用して解析しitem、その結果を に代入しc1、残りの入力を転送する」と言います。これは、itemパーサー内の関数を に割り当てるのではなく、現在の入力に対してc1内部で関数を実行した結果を割り当てます。item次にitem、 を使用して値を解析し、itemそれを何にも代入せず、残りの入力を転送する に到達します。c2 <- item次に、基本的に最初の行と同じことを行う に到達し、最後return (c1, c2)に に展開されParser (\cs -> Just ((c1, c2), cs))ます。これはreturn (c1, c2)が typeであることを意味しますParser (Char, Char)。型注釈を使用すると、次のようになります

takeThreeDropSecond :: Parser (Char, Char)
takeThreeDropSecond = do
    (c1 :: Char) <- (item :: Parser Char)
    (item :: Parser Char)
    (c2 :: Char) <- (item :: Parser Char)
    (return (c1, c2) :: Parser (Char, Char))

モナド do ブロックの最後の行は、メンバーである関数と同じ型でなければならないことに注意してください。return (c1, c2)has typeであるためParser (Char, Char)、 musttakeThreeDropSecondであり、その逆もあります。

于 2015-04-22T17:48:49.560 に答える