人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

HaskellでParsecが動かないので質問です

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/


●質問者: babanba_n
●カテゴリ:コンピュータ
○ 状態 :終了
└ 回答数 : 1/1件

▽最新の回答へ

1 ● ruicc
●300ポイント ベストアンサー

リンク先のコードを試してみたところ、問題なく実行出来ました。
恐らくそのコードを変更しつつ試していたのだと思いますが、原因は型推論の失敗であると思われます。


以下のコードで似たようなエラーが確認出来ました。
リンク先のコードに最後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.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ