2014-06-19

http://anond.hatelabo.jp/20140619010953

forループは全部再帰に直せるので再帰を使う。

f(a, b, total)みたいな関数を考える。

aはまだ読んでない値のリスト、bは既に読んだ値のリストtotalは読んだ値の総和を意味している。

まり、aの先頭をx、残りをxsとしたとき

f(xs, b+x, total+x)と再帰的にa,b,total更新していけば、一個ずつリストを読んでいくことができる。

後はf(randoms, [], 0)を呼んで、totalが50を超えたらbを返すようにすればいい。

まあこんなん実質変数使ってるみたいなもんじゃねえか、というハナシではあるけど。

関数型のメリットはパーツの再利用がやりやすいというところにつきると個人的には思う。

たとえばこれの応用として、総和が50を超えたらじゃなくて総和が素数になったら総和を返すような関数f2を作れと言われたら?

コピペしてif文の中だけ変える?

……手続き型の発想だけだとそうするしかないかもしれないけど、

関数型言語なら、fにcheckという引数を追加して、check(total)がtrueならbを返すようにすれば簡単にf2f3を作ることができる。

ラムダ式を使って、条件を判定する関数をその場でポンと作ってfに与えることもできる。(今はJavaとかC++ラムダ式使えるね)

再帰があんまり深くなりすぎるとStack Overflowになってしまったり、速度がどうしても犠牲になりがちだったり、

もちろん向き不向きはあると思うけど、関数型便利ですよと、そういう話でよかった?

記事への反応 -
  • 「ランダムな整数がランダムな個数引数に渡されて、それらを添字順にひとつずつ足して行き、50を超えたらそれまでの配列の中身を返す」みたいなのってどうやって書くんだろう。 ...

    • forループは全部再帰に直せるので再帰を使う。 f(a, b, total)みたいな関数を考える。 aはまだ読んでない値のリスト、bは既に読んだ値のリスト、totalは読んだ値の総和を意味している。 つ...

    • 純粋関数型のrandom関数は、入れたseedに対して必ず同じ数を返すので、一つ前の乱数を再びseedにするなら、純粋に書けるよ。 もちろん初期値がずっと一緒なら、起動するたびに同じ答え...

記事への反応(ブックマークコメント)

ログイン ユーザー登録
ようこそ ゲスト さん