haskellの合成関数とは?

このQ&Aのポイント
  • haskellの合成関数について調べてみました。合成関数は(.)という演算子で表されます。
  • 合成関数(.)は引数として一引数関数と定数関数を受け取り、それらを合成して新しい関数を作ります。
  • また、合成関数を使って二引数関数を合成することもできます。例えば、(+) . (+3) のような式は正しく評価されます。
回答を見る
  • ベストアンサー

haskellの合成関数について

haskell初心者です。 合成関数(.)について質問があります。 (.)関数の引数はghciの:tで調べると (.) :: (b -> c) -> (a -> b) -> a -> c と出てきます。 これは、第一引数に一引数関数、第二引数に一引数関数、第三引数に定数関数を取る、という解釈で合っていると思います。 また、ghciで次の式 ((+) . (+3)) 5 500 を評価しすると 508が出力されます、エラーはありません。 なぜ二引数関数の(+)を(.)の第一引数に入れてもエラーがでないのでしょうか。 おそらく僕のカリー化や合成関数に関する基礎知識が浅いためこのような疑問が生まれたのだと思います。できればこれらの知識を絡めた回答を希望しますが、わがままは言えません。 よろしくお願いします。

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

  • ベストアンサー
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

(+) を「二引数関数」と思っちゃうからいかんのよ. 「数値を引数にして『数値を引数にして数値を返す関数』を返す」なので, 引数は 1個.

puntero
質問者

お礼

回答ありがとうございます。 ということは(.)関数の(b -> c) のcは関数になるわけでしょうか?

その他の回答 (3)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.4

えぇと, 「組み合わせ理論」じゃなくって「組み合わせ論理」ね. 英語だと Combinatory Logic.

参考URL:
http://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%B3%E3%83%93%E3%83%8D%E3%83%BC%E3%82%BF%E8%AB%96%E7%90%86
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

補足です. c のみならず, a や b も関数型となることはあり得ます. 意味があるかどうかはさておき, 2つの引数に共通する型変数 b を同じものにできるなら「型付け」における問題は発生しません. 例えば foo :: Int -> Int -> Int bar :: (Int -> Int) -> Int -> Int のとき (bar . foo) という合成が可能で, その型は (bar . foo) :: Int -> Int -> Int となります. ちょ~ニッチな世界だけど, 組み合わせ論理を知っていると幸せになれる... かなぁ?

puntero
質問者

お礼

回答ありがとうございます。 もう一度一つ目の回答を考えるとなんとなくわかりました。 それと回答に挙がっている「組み合わせ理論」というのは数学における「組み合わせ理論」でしょうか。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

この場合は関数 (というよりは型だから「関数型」というべきか?) になります. ああ, 考えてみたら「第一引数に一引数関数、第二引数に一引数関数、第三引数に定数関数を取る、という解釈」がおかしいんだ. 合成した結果は関数なんだから, 本当は (b -> c) -> (a -> b) -> (a -> c) と読まなきゃならない.

関連するQ&A

  • 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' で右辺を表現しています。 疑問に感じるのは、 (>>=) 演算子を使用した場合、このような強引な事をしなければならないのか、それとももっとスマートな方法があるかということです。 よろしくお願いいたします。

  • 合成関数について

     こんばんは!ちょっと気になったのですが、  "f'(x)"が関数f(x)の導関数,"C"が積分定数を表すとき、  合成関数の微分法 [{f(x)}^n]' = nf'(x){f(x)}^n-1 が成り立つという事は、この関数の不定積分は、  ∫{f(x)}^n dx = [{1/(n+1)f'(x)}{f(x)}^n+1]+C としてもかまわないのでしょうか。  f(x)=ax+b のとき、  ∫(ax+b)^n dx = [{1/(n+1)a}(ax+b)^n+1]+C が成り立つので、関数全体としてはどうかなぁと思ったのですが・・・  よろしくお願いします。

  • [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しか使えません。 よろしくお願いします。

  • 【関数型言語,論理学】推論して関数を自動生成する

    こんにちは。 関数型言語(haskell)や論理学を独学している者です。 勉強中ふと思ったことがあるので質問します。(以降、表記はhaskell文法に倣います) 例えば今、我々に与えられた関数は (x -> Int)型の関数fと、(Int -> y) 型の関数gと((b -> c) -> (a -> b) -> a -> c)型の関数(.)だけだとします(a,b,c,x,yは全て型変数)。それ以外の関数は存在しません。 この時、(x -> y) 型の関数hは例えば(g . f)と表せると思います。 Int=b, x=a, y=cとみなせば、hは簡単に作れます。 しかし、それはあくまで人間にとって簡単だということです。 これを「計算機が作る」ことは可能でしょうか。 つまり、与えられた関数(と型の情報)だけで特定の型の関数を自動生成できるプログラムは存在し得るか、ということです。 カリー=ハワード同型対応という性質がありますね。これは簡単に言うと「ある型を持つプログラム(関数)が一つでも書ければその型に対応した命題は真」ということだと思いますが、僕が聞きたいのは「その命題(型)が真かどうか分からないけど、前提は用意するので証明(プログラム)は計算機に任せてもいいのか」ということです。 CoqやPrologという、計算機で証明を行うプログラミング言語があるというのは知っていますが勉強したことが無いのでよくわかりません。 よろしくお願いします。

  • 三角関数の合成

    三角関数の合成 π/6≦θ≦5/6πのとき、sin{2θ-(π/6)}-cos2θ の最大値と最小値を求めよと言う問題があります。 この式が √3/2 sin2θ-3/2 cos2θ という式になるのはわかりました。でもここからどのようにして合成するのでしょうか? 三角関数の合成の式が√(a^2+b^2) sin(θ+α) なので√3 sin(2θ+α) になるのはわかるのですがどうやってαの部分を出すのかわかりません… 図を書いて求めようとしたのですがさっぱりで… どなたか教えてください。よろしくお願いしますm(__)m

  • putchar(getchar())はなぜできない

    途中は省略しますが、 int main(void){ int c; c=getchar(); putchar(c); return 0; } はプログラムとして一文字入力・一文字出力しますが、 すこしプログラムを省略して   c=getchar(); putchar(c); を putchar(gerchar()); とすることは何故できないのか? プログラムの関数と数学の関数は違うという事や、int cでcがchar型でないこと。 これが数学の関数なら引数のない関数は数学にない事。 cは数学でいう代入ではなく、単なる箱で有ること。 getchar()の部分が'A'とかの定数なら領域として確保されているため、 int c; c='A' putchar(c)などせず、putchar('A') とできます。 又、この様な問題がHaskellのモナドに結びついていった。 など何となく分かりますが、いまいちきちんと説明できません。 宜しく願います。

  • 縦軸のみのベクトル合成 計算 エクセル 関数

    縦軸ののみのベクトル合成の計算を関数で行いたいです。 例えば、A点: +14.33、B点: +2.07、C点: -10.02 のとき、あるソフトでは+8.56という結果になるようですが、これを関数で計算するにはどういう数式で表せますか?

  • 三角関数の合成

    関数y=asinx+bsinxは、x=π/3のとき最大値6をとる。このとき、定数a、bの値を求めよ。 y=√a^2+b^2sin(x+α) と変形したり、 x=π/3とy=6を代入して 6=√3/2a+1/2b の形にしてみたりしたのですが、そこから先に進めず困っています。 どなたかお助けください;;

  • エクセルの関数を教えてください。

    初めて投稿します。よろしくお願いします。 エクセルの関数で苦戦しています。初歩的な関数しかわからないもので。。詳しい方、教えていただけますでしょうか。よろしくお願いします。うまく説明が伝わりづらいと思うのですが、、、 =SUM($A$1*B1,$A$2*B2,$A$3*B3・・・・)という式を入れました。(それぞれの掛算の合計を求めたい)括弧内の掛算は、60個ぐらいあって、引数が30個までしか指定できないので、エラーになってしまいます。そして、すごい長い式になっていて、指定するのにも一苦労です。 これをまとめる関数があるのでしょうか? 行  A B C D E F ・・・ 列 1 2 3 4 5 ・ ・ ・ 合計

  • 引数付自作関数において、引数を送らない場合について

    こんにちは。 makecolumn(a,b,c)という 自作関数があったとします。 ここで、 aとcにのみ、引数をおくり、 bは、デフォルト値を使いたいと 思います。 この場合、 makecolumn(30,,40) のようにすると、 どうも、エラーになってしまいます。 プログラム側では、 bの値について、 makecolumn=function(a,b,c){ if(b==null || b==''){ b=デフォルト値; } } としていますが、うまくいきません。 引数があるのに、空白で送ってきた場合に、 その状態を取得するには、 どうしたらいいのでしょうか。 よろしくお願いします。

専門家に質問してみよう