Haskell勉強中の初心者です
Parsecを使った構文解析を勉強中なのですが
(letter <|> digit)
という箇所で次のエラーが出てきます
No instance for (Text.Parsec.Prim.Stream s0 m0 Char)
arising from a use of `digit'
Possible fix:
add an instance declaration for
(Text.Parsec.Prim.Stream s0 m0 Char)
In the second argument of `(<|>)', namely `digit'
In the first argument of `many', namely `(letter <|> digit)'
In a stmt of a 'do' expression: cs <- many (letter <|> digit)
かなり初心者な質問なのでしょうがお答えいただければ幸いです
http://www.f13g.com/%A5%D7%A5%ED%A5%B0%A5%E9%A5%DF%A5%F3%A5%B0/Haskell/Parsec/
リンク先のコードを試してみたところ、問題なく実行出来ました。
恐らくそのコードを変更しつつ試していたのだと思いますが、原因は型推論の失敗であると思われます。
以下のコードで似たようなエラーが確認出来ました。
リンク先のコードに最後4行加えたものです。
import Text.ParserCombinators.Parsec run :: Show a => Parser a -> String -> IO () run p input = case (parse p "" input) of Left err -> do{ putStr "parse error at " ; print err } Right x -> print x word = do c <-letter cs<-many (letter <|> digit) return (c:cs) file = do f<-fileUnit f2<-file return (f++f2) <|> return "" where fileUnit = word <|> do c<-oneOf "-_./~" return [c] host = do u<-hostUnit h<-host return (u++h) <|> return "" where hostUnit = word <|> do c<-oneOf "-_." return [c] uri = do string "http://" h <- host f <- file return (h,f) main = run uri "http://example.com/hoge" --digitOrLetter :: Parser Char -- ここのコメントアウトを外すと動く digitOrLetter = digit <|> letter
最後から2行目のコメントを外すときちんと型推論が通り、動く様になります。
最後の行で定義したdigitOrLetterは「定義したのみ」であり、実際には使っていません。しかしその正に使っていないがために自身の定義から型を推論するしかなく、結果的に情報が足りず型推論が失敗してしまっているようです。なので、例えばmainを
main = print $ parse digitOrLetter "" "some input string"
このように変更し、digitOrLetterを使う様にすると、digitOrLetterの型は書かずともコンパイラが推論してくれます。
パーサコンビネータは型が自明な小さなパーサを大量に書くために、個々の型を省略することが多いのですが、このようなケースもあるのですね。
コメント(0件)