• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:Haskell: foldrの使用について)

Haskellのfoldrを使用したfilter関数の定義について

このQ&Aのポイント
  • Haskellのfilter関数は、foldrを使用して定義することができます。
  • foldrを使用すると、filter関数の定義をより短く書くことができます。
  • foldrを使用した場合、引数の意味がどのように指定されているのか不明瞭です。

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

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

No1の続きです。 何が問題で何を勘違いしているのかの方向性が分ったのできちんと回答します。 まず前提として 一番目に 質問のxとxsの間には":"が付いていないので、 xがリストの先頭要素xsが先頭要素を取り除いたリストではありません。 今回は、無名関数の第一引数と第二引数の意味しかありません。 ただし、型推論で推論された型を考えるとxsはリストでxはリストの要素という型になります。 二番目に foldr関数について自分で使えるぐらい十分に知っておいてください。 filter (>2) [1,2,3] を例にすると filter (>2) [1,2,3] ⇒foldr (\x xs -> if (>2) x then x : xs else xs) [] [1,2,3] 無名関数(\x xs -> if (>2) x then x : xs else xs)は長いのでとりあえずfとします。 f :: a -> [a] -> [a] なので fは二つ引数を持ち、一番目が任意の型で二番目が一番目の型のリスト fの戻り値の型は二番目の型と同じということが分ります。 ここ重要です。 fの一番目の引数が質問のxで二番目の引数がxsです。 No1にもあげたとおりこれが質問の回答です。 それ以上でもそれ以下でもないんですがさらに具体的にしないと分からないと思うので、 さらに計算を続けて、 foldr (\x xs -> if (>2) x then x : xs else xs) [] [1,2,3] ⇒foldr f [] [1,2,3] foldrの定義にしてがって ⇒1 `f` (2 `f` (3 `f` [])) `f`の意味を知らないかもしれないので、`を使わない形に変換する ⇒f 1 (f 2 (f 3 [])) 便宜上外側のfからf1 f2 f3する。 質問のx とxsに当てはめると f1の場合 x は1 xs は(f 2 (f 3 [])) f2の場合 x は2 xs は(f 3 []) f3の場合 x は3 xs は[] となります。

tsuki7
質問者

お礼

foldrの定義自体は知っていました。ただ、xが値、xsをリストであることを どうやってコンピュータは理解していたのであろうと考えていました。 型推論なんですね。 無名関数の、 if (>2) x then x : xs else xs によって、推論されていたということだとわかりました。 ありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (1)

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

例に挙げていたこれ >filter (+) [1,2,3] はコンパイルが通らないのでなんかのミスと思います。 filter (>2) [1,2,3] とかの間違いかな。 また、コンピュータの理解の意味が分らないので勝手に質問を解釈すると 質問の意図は >filter p = foldr (\x xs -> if p x then x : xs else xs) [] の x とxs って何のことか教えてくださいということでいいでしょうか? 結論だけ答えると、 foldr の第一引数の一番目の引数と2番目の引数を示しています。 これ以上書くと質問の意図とずれた時が無駄なので、今回はここでやめておきます。

tsuki7
質問者

補足

>filter (>2) [1,2,3] すみません、関数の勘違いで、上記の場合と考えていただけたら良いです。 x,xsはそれぞれリストの先頭要素、xsは先頭要素を取り除いたリストであること は理解しています。 ただ、xやxsはコンピュータ的に見ると、適当に名前をつけた仮のものですよね。 xはリストでなくひとつの数でないといけないことや xsは数でなくリストでないといけないことはどうしてわかるのでしょうか。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • Standerd MLでリストの先頭から2つずつ要素を組にしたリストを作りたい

    Standerd MLの問題で整数のリストの先頭から2つずつ要素を組にしたリストを求める関数でcomを作りたい。 'a list->('a*'a)listでcom([1,2,3,4])の場合は([1,2],[3,4]),元の要素数が奇数の場合は0を入れる。 自分で途中までは考えれました。 fun com(nil)=nil | com(x::xs)= if xs=nil then x::0 else x::sx | com(x::xs::xxs)= if xxs=nil then x::xs else com(xxs); これで実際に正常に動作するかどうかわかりません。 ご指導よろしくお願いします。

  • Filter関数を用いた結果、何も検索されなかった場合

    Filter関数を用いた結果、何も検索されなかった場合 以下のプログラムを実行したところ、セルはまっさらのまま。   Sub Macro3()     Dim a As Variant     a = Array(1, 2, 3, 4, 5)     ActiveCell.Value = Filter(a, 8)   End Sub そこで   If Filter(A,8) = "" Then ・・・(1)     ActiveCell.Offset(1, 0).value = False   Else表示     ActiveCell.Offset(1, 0).value = True   endif を書き加えてみましたところ、   実行時エラー'13':   型が一致しません とのエラーが出ます。 (1)を   If ActiveCell.value = "" Then と書く分には問題ないのですが、だからと言って、Filter(A,8)の値は""で表せないのですね。 とりあえずこの五行はエラーが出ているので削除しました。 次に   ActiveCell.Offset(1, 0).Value = IsEmpty(Filter(A, 8)) を書き加えると、アクティブセルの一つ下は「False」となります。Filter(A,8)では何も抽出されないのですから、空か否かを問われたら「True」のはずなのですが・・・やはり何か戻り値があるのですね・・・ ではエラー値が戻っているのかと   ActiveCell.Offset(2, 0).Value = IsError(Filter(A, 8)) を書き加えると、「False」ですからエラー値ではありません。   If Filter(A,8) = Null Then ・・・(2)     ActiveCell.Offset(3, 0).value = False   Else表示     ActiveCell.Offset(3, 0).value = True   endif を書き加えたところ、またも   実行時エラー'13':   型が一致しません とのエラーが出ます。 (2)を   If Filter(A,8) = Error Then と書き換えてみても同じです。 試しに(2)を   If Cvar(Filter(A,8)) = Null Then としてみたり   If Filter(A,8) = Cvar(Null) Then としてみたり   If Cvar(Filter(A,8)) = Cvar(Null) Then としてみたりしましたが、同じエラーが出ます。 Ubound(Filter(A,8)の値は-1です。これをもってこの場合の戻り値とするしかないのでしょうか。filter関数の戻り値が分からないからUbound関数を使っていることがモロばれで、嫌なんです。   If Filter(A,8) = なんとか Then のなんとかに入る戻り値をどなたか教えてください。

  • うまくできない??NO2

    Private Sub P1_Click(Index As Integer) If Index = 1 Or 2 Or 3 Or 4 Or 5 Then If P1(1).BackColor = vbRed Then P1(1).BackColor = vbBlue Else P1(1).BackColor = vbRed End If If P1(2).BackColor = vbRed Then P1(2).BackColor = vbBlue Else P1(2).BackColor = vbRed End If If P1(3).BackColor = vbRed Then P1(3).BackColor = vbBlue Else P1(3).BackColor = vbRed End If If P1(4).BackColor = vbRed Then P1(4).BackColor = vbBlue Else P1(4).BackColor = vbRed End If If P1(5).BackColor = vbRed Then P1(5).BackColor = vbBlue Else P1(5).BackColor = vbRed End If '------------------------------------------------------------------- ElseIf Index = 6 Or 7 Or 8 Or 9 Or 10 Then ~~~~~ 省略 ElseIf Index = 21 Or 22 Or 23 Or 24 Or 25 Then If P1(21).BackColor = vbRed Then P1(21).BackColor = vbBlue Else P1(21).BackColor = vbRed End If If P1(22).BackColor = vbRed Then P1(22).BackColor = vbBlue Else P1(22).BackColor = vbRed End If If P1(23).BackColor = vbRed Then P1(23).BackColor = vbBlue Else P1(23).BackColor = vbRed End If If P1(24).BackColor = vbRed Then P1(24).BackColor = vbBlue Else P1(24).BackColor = vbRed End If If P1(25).BackColor = vbRed Then P1(25).BackColor = vbBlue Else P1(25).BackColor = vbRed End If End If '------------------------------------------------------------------ 続く・・・ 関連URL:http://oshiete1.goo.ne.jp/kotaeru.php3?qid=418248

  • セルのIF分の質問です

    セルに入れる IF分を 教えてください NGを 分解してみたのですが・・・・ =IF(N3=1,then     -M2, else     IF(K2=1, then       IF(M2<P3-M3, then          M2      Else         P3-M3,       endif      else          IF(K2=-1,then           IF(M2<M3-P3,then               M2,           Else               M3-P3,            endif         else            0         endif)       endif) endif) N3 は 1 もしくは 0。 K2 は 1,-1,0 の3通りです IF が 5個ですから ) も 5個?(ENDIF も 5個 だし?) といった ことで お手数ですが

  • BASICプログラミング &の使い方

    (A)IF a>=b THEN LET x=a & & ELSE LET x=b (B)IF a>=b THEN LET x=a ELSE LET x=b 学校でもらったプリントに 「1つの文を複数行に渡って書くときは&を使うと」書いてあるのですがなぜBの文では使ってないのでしょうか? &の使い方がわからないので教えてください。

  • うまくできない??NO3

    If Index = 1 Or 6 Or 11 Or 16 Or 21 Then If P1(1).BackColor = vbRed Then P1(1).BackColor = vbBlue Else P1(1).BackColor = vbRed End If If P1(6).BackColor = vbRed Then P1(6).BackColor = vbBlue Else P1(6).BackColor = vbRed End If If P1(11).BackColor = vbRed Then P1(11).BackColor = vbBlue Else P1(11).BackColor = vbRed End If If P1(16).BackColor = vbRed Then P1(16).BackColor = vbBlue Else P1(16).BackColor = vbRed End If If P1(21).BackColor = vbRed Then P1(21).BackColor = vbBlue Else P1(21).BackColor = vbRed End If '-------------------------------------------------------------------- ElseIf Index = 2 Or 7 Or 12 Or 17 Or 22 Then ~~~省略 ElseIf Index = 5 Or 10 Or 15 Or 20 Or 25 Then If P1(5).BackColor = vbRed Then P1(5).BackColor = vbBlue Else P1(5).BackColor = vbRed End If If P1(10).BackColor = vbRed Then P1(10).BackColor = vbBlue Else P1(10).BackColor = vbRed End If If P1(15).BackColor = vbRed Then P1(15).BackColor = vbBlue Else P1(15).BackColor = vbRed End If If P1(20).BackColor = vbRed Then P1(20).BackColor = vbBlue Else P1(20).BackColor = vbRed End If If P1(25).BackColor = vbRed Then P1(25).BackColor = vbBlue Else P1(25).BackColor = vbRed End If End If '--------------------------------------------------------------------- End Sub ※みにくくてすいません リンクを張るのは禁止らしいので・・・できないですね・・・ 関連URL:http://oshiete1.goo.ne.jp/kotaeru.php3?qid=418248 関連URL:http://oshiete1.goo.ne.jp/kotaeru.php3?qid=418250

  • VB初心者ですAccessを更新したいのですが

    VB初心者です、よろしくお願いします。 VBでAccessのレコードの一項目を更新したいのですが出来ません。 抽出条件からAccessのデータを持ってきた後、更新したいのですがどうすればいいのでしょうか? 因みに抽出条件までは変更できません、AddNew以降でお願いします。 VB6でAccess2003です。 エラーは現在のRecordsetは更新をサポートしておりませ。プロダイバーかロックタイプの限界の可能性があります。 Set rst = New ADODB.Recordset '処理をするテーブル指定 rst.Open "[**]", db, adOpenStatic, adLockOptimistic With rst .MoveFirst .Filter = "" criteria1 = "" criteria1 = "**= '" & Module1.** & "'" .Filter = criteria1 If .RecordCount = 0 Then MsgBox "は登録されていません" Else .Filter = "" criteria2 = "" criteria2 = "**= '" & Module1.** & "' " .Filter = criteria2 If .RecordCount = 0 Then MsgBox "登録されていません" Else .Filter = "" criteria3 = "" criteria3 = "**'" & Module1.** & "' " .Filter = criteria2 If .RecordCount = 0 Then MsgBox "登録されていません" Else Module1.** = rst.Fields("**") .AddNew .Fields("***") = Module1.** .Update End If End If End If End With

  • 線形補間法プログラム(C++)

    C++言語で線形補間法のプログラムを組んで実行しているのですが、どしてもうまくいきません。ただ2倍の画像を作っているだけなのですが・・・。 以下プログラムを載せます、おおよその場所はわかるのですがどうすれば通るのかわかりません。どう直したらよいのか分かる方がいましたらご教授お願いします。 ※bmp[0]:現画像 pic:bmp[0]の縦横2倍の画像 // 線形補間法 // int zx = 2; int zy = 2; int i,j,m,n; float x,y,p,q; int xs = bmp[0]->Width/2; int ys = bmp[0]->Height/2; int d; for(i = -ys; i < ys; i++){ for(j = -xs; j < xs; j++){ y = i/zy; x = j/zx; if(y > 0){ m = (int)y; }else{ m = (int)(y-1);} if(x > 0){ n = (int)x; }else{ n = (int)(x-1);} q = y - m; p = x - n; if(q == 1){q = 0; m = m + 1;} if(p == 1){p = 0; n = n + 1;} if((m >= -ys)&&(m < ys)&&(n >= -xs)&&(n < xs)){ d = (int)((1.0 - q) * (1.0 - p) * (bmp[0]->GetPixel( m + ys, n + xs)) //おそらくこの辺に問題があるかと思われます。 + p * (bmp[0]->GetPixel( m +ys, n + xs)) + q * (1.0 - p) * (bmp[0]->GetPixel(m + 1 + ys, n + xs)) + p * (bmp[0]->GetPixel(m + 1 + ys, n + 1 + xs))); }else{ d = 0; } if(d < 0){d = 0;} if(d > 255){d = 255;} pic->SetPixel(i + ys, j + xs) = d; } } pictureBox2->Image = pic; }

  • 二分探索木のプログラム

    2分探索木のプログラムを作っているのですが、実行するとセグメテーション違反がでます。何が間違っているんでしょうか? #include<stdlib.h> struct node{ struct node *left,*right; int datum; }; struct bintree{ struct node *root; }; /*空木を作成*/ void InitTree(struct bintree *p) { p->root=NULL; } /*木全体を削除*/ void ClearTree(struct bintree *p) { struct bintree *q,*r; if(p->root!=NULL){ q->root=p->root->left; ClearTree(q); r->root=p->root->right; ClearTree(r); free(p->root); } } /*第二引数で指定された値が木の節点のラベルに存在すれば、その節点へのポインタを返す。なければ、NULLを返す。*/ struct node * SearchNode(struct bintree *p,int x) { struct bintree *q,*r; struct node *a=p->root; int cond=x-(a->datum); if(a==NULL) return NULL; else if(cond==0) return a; else if(cond<0){ q->root=p->root->left; SearchNode(q,x); } else{ r->root=p->root->right; SearchNode(r,x); } } /*第二引数で指定された値が木の節点のラベルに存在すれば、NULLを返す。なければ、追加して、新たに作成された節点へのポインタを返す。*/ struct node * InsertNode(struct bintree *p,int x) { struct bintree *q,*r; struct node *a=p->root; int cond=x-(a->datum); if(a==NULL){ a=(struct node *)malloc(sizeof(struct node)); a->datum=x; a->left=a->right=NULL; return a; } else if(cond==0) return NULL; else if(cond<0){ q->root=p->root->left; a->left=InsertNode(q,x); } else{ r->root=p->root->right; a->right=InsertNode(r,x); } } int main() { struct bintree *p; struct node *a; InitTree(p); a=InsertNode(p,5); InsertNode(p,3); InsertNode(p,0); InsertNode(p,10); SearchNode(p,5); ClearTree(p); return 0; }

  • emacsでcmmon lispのプログラムを作成します。

    emacsでcmmon lispのプログラムを作成します。 my-equal(A, B)= if A is an atom then if B is an atom then (eq A B) else if B is an atom then nil else if (car A)=(car B) then (cdr A)=(cdr B) else nil というのです。自分が考えたのは、 defun my-equal(x, y)= (cond ((atom x) (atom y)) (eq x, y) (atom) (t, nil) ((car x)=(car y) (cdr x)=(cdr y)) (nil)) というのでよろしいのでしょうか? また、4行目(この全文の)の意味がいまいち分かりません。

このQ&Aのポイント
  • インク4色のうち、ブラック(インク残量満タン)が全く印字されないトラブルについて相談したい。クリーニングを数回実施し、テストプリントしたが黒だけ全く印字されない状況となり困っている。
  • Windows10を使用しており、無線LANとUSBケーブルで接続している。
  • CTV回線を使用している。
回答を見る