解決はしたけれど...納得にはまだまだ遠い! だけど、先に進むよ。

in

昨日(前エントリ)の続き。いろいろ試した結果

p = item Main.>>= \x ->
    item Main.>>= \y ->
    item Main.>>= \z ->
    Main.return (x,z)

で、いけました。「Programming in Haskell]Chapter 8.4(p77)には、

p1 >>= \v1 ->
p2 >>= \v2 ->
:
pn >>= \vn ->
return (f v1 v2 .. vn)

p = do v1 <- p1
       v2 <- p2
       :
       vn <- pn
       return (f v1 v2 .. vn)

は同等だよって書いてあるのでいいとは思うのですが、同じならなんでdo式を使うとエラーになるんだ?と考えてみると、昨日は関係ないかとも思ったのですが、やっぱり怪しいのは(>>=)。

"p1 >>= \v1 ->"と"v1 <- p1"が置換可能であるなら、(<-)は(>>=)の定義に依存していて、今回のプログラムで言えば"x <- item"は"Main.>>="ではなくて"Prelude.>>="に引きずられているのじゃないかという気がします。試しに、

p = item Prelude.>>= \x ->
    item Prelude.>>= \y ->
    item Prelude.>>= \z ->gt;
    Main.return (x,z)

と書いてみれば、

Couldn't match expected type `Char'
against inferred type `[(Char, String)]'
In the expression: x
In the first argument of `Main.return', namely `(x, y)'
In the expression: Main.return (x, y)
Failed, modules loaded: none.

やっぱり、xはCharではなくて`[(Char, String)]'なんでおかしいよ!って言われます。

このことについては(読み落としがなければ)まだ解説されていなくて、同書では、単に">>="とか、"<-"しか書いてありません。ただ、hugsでもghciでもただ単に">>="って書くと、曖昧だよ!って言われるので全然見当違いな仮説でもないかと思います。読み進めば解説がでてくるのかもしれませんが、どうすればdo式の書き方でうまくいくのか?これ以上悩んでも先に進めないのでとりあえずこれで仮納得することにしときます。

もう一つ、昨日の段階では、エラーメッセージに引きずられてxやyは"[(Char,String)]"と思い込んでいましたが、"x < item"と"item Main.>>= \x->"と同等だと考えればxは、"item Char"の引数"Char"がってことになります。(よね?)そうでないとまたまた"Main.return (x,y)"で悩むことになりますんで。結果を見てのこじつけ感ありありですが、とにかく停滞するより先に進みたいので、いつかこの霧が晴れることを期待しつつ納得することにします。

それにしても、今は全然違う脳みそ使っている気がしますね。疲れますが、楽しいです。

添付サイズ
chap8_1.hs1.14 KB

この記事のトラックバックURL:

http://hippos-lab.com/blog/trackback/331

返信