[Haskell] handle関数がうまくいかない

このQ&Aのポイント
  • RealWorldHaskellという本を読んでいて解決できないところがあったので質問します。
  • Control.Exceptionには例外を扱うhandle関数というものがあります。
  • 具体的に言えばコンパイルするとhandle (\_ -> return Nothing ) の部分でAmbiguous type variable `e0' in the constraint:とエラーは吐きます。
回答を見る
  • ベストアンサー

[Haskell]handle関数がうまくいかない

RealWorldHaskellという本を読んでいて解決できないところがあったので質問します。 Control.Exceptionには例外を扱うhandle関数というものがあります。 型シグネチャは Exception e => (e -> IO a) -> IO a -> IO a です。 1つ目の引数に例外を捉えた場合実行する関数を、2つ目の引数に例外を投げる可能性のある関数を与えます。 1つ目の引数の関数の返り値の型と2つ目の引数の型は同じでなければなりません。 次の関数はhandle関数を利用して安全にファイルサイズを取得する(つもりで作った)関数です。 getFileSize :: FilePath -> IO (Maybe Integer) getFileSize path = handle (\_ -> return Nothing ) $ bracket (openFile path ReadMode) hClose $ \h -> do size <- hFileSize h return (Just size) この関数がうまくいきません。 具体的に言えばコンパイルすると handle (\_ -> return Nothing ) の部分で Ambiguous type variable `e0' in the constraint: とエラーは吐きます。 しかし、返り値の型はNothingでMaybe Integerと合致していると思います。 なのにAmbiguousです。 なぜこうなるのかわかりません。 ちなみにControl.OldExceptionでもhandle関数が定義されていますが、ghcのバージョンが新しいせいか(7.0.2)コンパイルできません。 なのでControl.Exceptionしか使えません。 よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • qoopty
  • ベストアンサー率100% (3/3)
回答No.1

適当なファイルに以下の内容内容を貼り付けてコンパイル/実行してください。 -- ここから-- {-# Language ScopedTypeVariables #-} import Control.Exception import System.IO getFileSize path = handle (\(e :: SomeException) ->return Nothing) $ bracket (openFile path ReadMode) hClose $ \h -> do {size <- hFileSize h; return $ Just size} -- ここまで-- 参考サイトです。ここを理解すればなんでダメだか分かるはず。 http://itpro.nikkeibp.co.jp/article/COLUMN/20081104/318426/?ST=ittrend

関連するQ&A

  • 関数のプロパティ

     まるっきりわからないので、取り止めのない話になってしまいますが普通、関数で引数・返り値・リターン値ってありますよね。それ以外に関数自体がプロパティを持っていてそれがもう1つの引数や返り値になるってチョコって聞いたんですけど、、。それでGetやLetを使うそうなんですけど、、。どなたか知りませんか?

  • GetFileSizeの最大

    GetFileSizeは関数が失敗すれば、0xFFFFFFFFを返します。 説明のために、DWORDが4ビットだったとすると、 GetFileSizeが失敗して 1111が返ることになると思います。 そうすると、返り値で得られる最大サイズは0111ですか? 第2引数を使った場合は、0111と1111を合わせたものが最大サイズで、 実際だと、01111111111111111111111111111111と、1が32個を合わせた、 16進数だと、7FFFFFFFとFFFFFFFFを合わせた、 10進数だと、2147483647と4294967295を合わせた 6442450942 (6ギガぐらい) が、GetFileSizeで得ることができる 最大ファイルサイズですか?

  • C言語の関数について。

    学校の課題がわからないので教えてください。 1. 次の関数recfunc()は関数内で自分自身を呼び出す再起関数である。 int recfunc(int x){ if(x<=0)return -1; else if(x==1) return 3; else return 3*recfunc(x-1)-2; } 引数に1,2,3,4,5,...を与えたときの返り値を求めよ。その結果から、一般に 整数値nが与えられたとき、どのような値が計算されるか推測せよ。 一体何を返す関数だろうか?またどのようにその計算が実現されているか を簡潔に述べよ。 2.どのような再帰関数も、再帰を用いない関数に書き換えることができる。 問題1の関数recfunc()と同じ引数、同じ返り値をもつ再帰を用いない関数 func()を作成せよ。 2問も質問してすみません。 このプログラミングのレポートを提出しなくてはならないので困ってます。 何卒よろしくお願いします。

  • プロセスのハンドルと識別子

    エディットやボタンなどへのアクセスは、ウインドウハンドルを使ってそれらのオブジェクトにアクセスしているんだと考えられますが、 プロセスやスレッドにはハンドルと識別子の両方があるので、その違いが分かりません。 あるスレッドが動いていて、それを止める場合、そのスレッドのハンドルを使うのか識別子を使うのかが想像できるようになりたいのです。 プロセスを終わらせる関数を見つけ、その関数の引数の型を調べるのではなく、ハンドルと識別子の違いを理解して、それを想像する方法を教えてください。

  • 関数の定義

    関数の定義とは ここから 戻り値の型 関数名(引数リスト) {   文;   ・・・   return式; } ここまで のことをいうのでしょうか??あたりまのような質問ですみません。 参考書には、「関数の定義はブロック内にまとめて記述します」 となっているので{ }の中のものだけなのかと思ってしまいました。 初歩的な質問ですがよろしくお願いします。

  • 例外処理と、ハンドルする範囲

    Try Catchや、throws Exceptionを使うべき時についてです。 ・0除算がありうるとき ・DLLや外部EXEを使用するとき、そっちの世界でのエラーをハンドルするとき ・ネットワークエラーや、DBサーバでのエラーをハンドルするとき ・ディレクトリがないとき・ファイルがないとき ・リフレクション?で、型判定・キャストを使用するときに、意図しない型のクラスが渡されてきた場合 などは、ハンドリングしつつ、それ用のエラーページにてエラーを表示しようと思いますが、 (1)みなさんはどのようなものまでハンドリングしていますか? 自分は、 Catch ex As System.xxx.xxxxxxException を何種類も書くメリットが感じられないので、 catch (System.Exception ex) で、上のもの以外のエラーについて、ex.Messageを出力しています。 (2)例外があったとき、エラーページに飛ばさずに、呼び元に扱いを任せる場合は(throwsさせる場合)どう使い分けをしていますか? (3)呼び出された側のクラスの、catch (Exception e)のブロックの中で、エラーページに飛ばしていますか?それとも、一番最初の呼び出し元まで、throws→throws→throws...して、一番最初の呼び出し元からエラーページに飛ばしていますか? .

  • VBAでコントロールのハンドルを取得したい

    Excel2000のVBAでFormに配置したコントロールのハンドルを取得するにはどうしたらよいのでしょうか? 目的は、Winsock API(ws2_32.dll)の WSAAsyncSelect関数の2番目の引数にセットする値を取得することです。USER32.dll の GetDlgItem が使用できそうなことがわかったのですが、こちらもその2番目の引数にセットするIDがわかりません。

  • C++ strlenに関して

    visual studio 2010を使ってC++の勉強を始めました。 これまではJAVAによる開発をやっていました。 strlenの定義を観ようと思い定義へ移動すると string.hの中に下記のように書かれていました。 -------------------------------------------------------------------- _Check_return_ size_t __cdecl strlen(_In_z_ const char * _Str); ----------------------------------------------------------------------- 初歩的な事かもしれないのですが、上記のコードの意味が理解できず 困っております。 返り値の型 関数名strlen(引数の型); という順番で書かれているものと思っているのですが、 返り値が下記3つ有るという事でしょうか? ・_Check_return_ ・size_t ・__cdecl また、引数const char * _Strの部分は変更不可能なchar型へのポインタ という事だと解るのですが、 _In_z_が何を意味しているのか理解できません。 --------------------------------------------------------------------------- #define _In_z_ _Pre_z_ _Deref_pre_readonly_ ---------------------------------------------------------------------------- と書かれているのですが、 #define A B でBをAで置き換えるという事だと思っているのですが、 #define A B C となっている場合はどういう意味になるのでしょうか?

  • EXCEL2010の関数

    EXCEL2010の関数の解説でお勧めの書籍があれば教えてください。 ポイントは、関数の引数の型や、検索や設定範囲の条件です。 たとえば、 この関数は検索範囲は一列でないとだめ この関数は2次元の範囲でもOK などということがすぐにわかるような書籍が希望です。 持ち歩きたいので小さいサイズの書籍がうれしいです。文庫サイズとは言いませんが、A4とかで厚さが2センチもあるとかはご勘弁。

  • Haskell の do 式について

    Haskell を勉強中ですが、オーム社の「プログラミング Haskell」 の第8章 「関数型パーサー」のところでつまづいています。 「ふつうのHaskellプログラミング」も読んでいます。 関数型パーサーの章ではモナドという言葉は使わずに、実はモナドの解説?と思っているのですが... ここからが本題で、 do式 というのは、 (>>=)演算子の記述をもっと直感的に表すためのシンタックスシュガーと理解しています。実際、以下のように記述すると A B \n が順序良く出力されます。 echoAB1 = do { putChar 'A'; putChar 'B'; putChar '\n'; } ここで、シンタックスシュガーである do 式を使わない方法を考えた場合、 echoAB2 = putChar 'A' >>= \x -> putChar 'B' >>= \x -> putChar '\n' とこの様になるかと思い、実際、同じような結果となります。 1つ目の(==>)演算子の左辺は、 IO() なので 右辺の型は () -> IO a でなければならないので、しょうがなく 1つの引数を受け取るλ式 \x -> putChar 'B' で右辺を表現しています。 疑問に感じるのは、 (>>=) 演算子を使用した場合、このような強引な事をしなければならないのか、それとももっとスマートな方法があるかということです。 よろしくお願いいたします。

専門家に質問してみよう