スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

F#入門第19回(リストを引数にとる関数(2))

今回のお題は「リストを引数にとる関数(2)」です。
 
 まずは宿題の答えです。
 List.filterとList.lengthを用いてList.existsと同じ働きをする関数myListExistsを定義してください。定義は
 let myListExists f list = で始めてください。
 (答え)
 
 let myListExits f list =
     if List.length (List.filter f list) > 0 then
         true
     else
         false
 
 さて次はList.foldという関数の紹介です。
 まず[1;2;3]というリストがありこれの和を求めたいとします。
 自分でどうするかと考えてみると次のようになるかと思います。
 まず1をとってきます、これに2を足して3とします。
 更にこれに3を足して結果が6
 しかしこれでは、最初の要素に対してだけ、操作が異なるので、次のような方法を考えてみてください。
 最初に答えの種となる0を用意する。これと最初の要素1の和を次の種とする(ここで種は1)。これと次の要素2の和を次の種(ここで種は3)とする。最後までいったら種を返す。(一般には、育っていく種のことを、蓄積していくものという意味合いでaccumulaterといいます。)
 このような操作用の関数がList.foldです。
 例
 
 > List.fold (+) 0 [1;2;3];;
 val it : int = 6
 
 上の例では0を種にして、まず(+) 0 1 が評価されて、1となり、次にこれが次の種となり(+) 1 2 が評価されて3となり、次にこれが次の種となり(+) 3 3 が評価されて6となり、ここですべての要素がつくされたので、6が返り値として、返ります。
 
 > List.fold (*) 1 [1;2;3;4];;
 val it : int = 24
 
 これは(((1*1)*2)*3)*4が計算されています。
 
 よって
 
 let f1 n =
     List.fold (+) 0 [1 .. n]
 
 とすれば、f1は1からnまでの和を返す関数となりますし、
 
 let f2 n =
     List.fold (*) 1 [1 .. n]
 
 とすれば、f2はnの階乗を返す関数になります。(nを大きくするとすぐ桁あふれしてしまいますが。)
 
 一般のList.fold はList.fold 関数 種 リスト
 の形なのです。関数は「リストの要素を見て、種を育てる」、すなわち種と(リストの要素)を引数にして、新しい種を育てる関数である必要があります。
 List.foldの型を見てみると次のようになっています。
 
 > List.fold;;
 val it : (('a -> 'b -> 'a) -> 'a -> 'b list -> 'a) = <fun:clo@0>
 
 'aが種の型、'bがリストの要素の型になっているわけです。
 (('a -> 'b -> 'a) -> 'a -> 'b list -> 'a)
  種を育てる関数     種     リスト   育った種
 
 
 例として、int型のリストを引数にして、その中で3で割り切れる数、3で割って1余る数、3で割って2余る数が、いくつずつあるか、タプルにして返す関数countMod3を定義してみます。(例えば test [1;4;3] なら(1,2,0)と返す関数です。)
 
 let countMod3 lst =
     let grow (r0,r1,r2) ele =
         if ele % 3 = 0 then
             (r0+1,r1,r2)
         elif ele % 3 = 1 then
             (r0,r1+1,r2)
         else
             (r0,r1,r2+1)
     List.fold grow (0,0,0) lst
 
 上の定義で、grow が種を育てる関数です。
 
 実行例
 
 > countMod3 [1;4;3];;
 val it : int * int * int = (1, 2, 0)
 
 List.map と List.foldはF#で多用する関数です。
 
 それでは、宿題です。
 
 (1)F#にはfloat 型のリストを引数にして、それの平均を返す関数List.averageが準備されていますが、List.fold とList.lengthを使って自分でmyListAveを定義してみてくだい。
 引数が[]の時のことは、考えなくてもよいです。
 (Hint :vをfloat 型に変換するにはfloat v とします。)
 
 (2)float*floar型のタプルのリストを引数にして、タプルの第一成分が第二成分より大きい要素の個数、等しい要素の個数、小さい要素の個数をタプルにして返す関数myCountを定義してください。
 例えばmyCount [(2.0,1.1);(3.0,3.0)]は(1,1,0)を返します。
 
スポンサーサイト

テーマ : プログラミング
ジャンル : コンピュータ

コメントの投稿

非公開コメント

プロフィール

T GYOUTEN

Author:T GYOUTEN
F#と英単語とフリーソフトと読書に興味があります。
ホームページでフリーソフトも公開しています。どぞ御贔屓に。

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
フリーエリア
フリーエリア
blogram投票ボタン
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QRコード
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。