見出し画像

関数型プログラミングで解くリスト構造の初級問題-5問目- (約5分)

 関数型プログラミングによるリスト操作の練習問題の5問目です。問題は、OCaml公式ページのものを使いました。
 内容は、問題と答案です。答案には、OCaml版とJavaScript版があります。OCaml版の作成時間は、約5分でした。

問題5.

 所与のリストを反転したリストを求める関数revを書け。

答案

考え方

 関数型プログラミングによるリスト操作の基本的な流れは、以下の1から3になります。
  1. 引数のリストをheadとtailに分離する
  2. tailを引数として再帰呼び出すると共に、その返り値とheadを適当に組み合わせる
  3. 以上を引数のリストが停止条件に達するまで繰り返す

 まず、停止条件から考えます。引数のリストが空リストの場合、その空リストを反転したリストは、また空リストになります。
 これより、停止条件は「リストが空であること」になり、その返り値は空リストになります。

 次に、headとrev tailの組み合わせ方を考えます。
 引数のリストを反転すると前後が逆さまになります。
 このとき、先頭の要素であるheadは、反転後のリストでは末尾の要素でなければなりません。
 そこで、headをrev tailの返り値に後ろ側から結合します。
 ただし、結合に@演算子を用いるので、headではなく、headを唯一の要素とするリスト[head]を@に渡します。

コード

OCaml

let rec rev = fun lisuto -> match lisuto with
 | [] -> []
 | head::tail -> rev tail@[head]

JavaScript

var rev = new Function ('list', 'return list.length == 0 ? list : rev (list.slice (1, list.length)).concat (list[0])');

 JavaScriptには、リストがないので配列を使用しました。

感想

OCaml

 答案はすぐに思いつきました。しかし、この答案だと、引数のリストが長い場合にスタックを使い切りそうな点がいまいちです。

JavaScript

 なぜだかjdkにjjsが含まれていなかったで、実行環境を整えるのが面倒くさかったです。
 プログラムの間違いをなるべくコンパイルエラーで捉える方針が好きなので、弱い型付けのJavaScriptは好きになれません。
 クラスベースではないオブジェクト指向言語であるSelfの子孫なので、歴史的には興味深いですが、それだけです。他の言語のような魅力を全く感じません。

再開

 前回「ビュー数が少ないので止める」と書きました。
 しかし、私の渾身のオリジナル記事よりも、ビュー数が多かったので再開することにしました。渾身のオリジナル記事よりも


いいなと思ったら応援しよう!

佐野 聡
古往今来得ざれば即ち書き得れば即ち飽くは筆の常也。と云うわけで御座います、この浅ましき乞食めに何卒皆々様のご慈悲をお願い致します。