見出し画像

関数型プログラミングの初級問題-18問目- (約10分)

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

問題18.

 所与のリストにおけるi番目からk番目までの要素を切り取って部分リストを生成する関数sliceを書け。
(要素は0番目から数えます。i番目およびk番目の要素は部分リストに含まれます。)

※ 例えば、slice ["1"; "2"; "3"; "4"; "5"] 1 3は(["2"; "3"; "4"])になります。

答案

基本的な考え方

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

本問の解き方

 リストの先頭から要素を順に辿りつつ処理を行います。
 処理は、対象としている要素の順番に従い三つに分かれます。
 まず、i番未満のときは、何もせずに次の要素の処理に移行します。
 次に、i番以上k番以下のときは、headを::演算子で再帰呼び出しの返り値に結合します。
 最後に、k番を越えたときは終了します。

コード

let slice lisuto hajimari owari =
 let rec extract j = function
  | [] -> []
  | head::tail ->
   if owari < j then []
   else if j < hajimari then extract (j+1) tail
   else head::extract (j+1) tail in
extract 0 lisuto


 

感想

 今回の答案は今までのなかで最悪の出来です。特に、実質的な処理を行うextract関数が末尾再帰のようになっているのに吐き気を催します。

 末尾再帰でしかコードを書けないのなら素直に命令型プログラミングをするべきです。未練がましく関数型プログラミングを装うのは大変にみっともないです。

 引数に渡している0も頭が悪いとしか言いようがありません。
 そもそも、問題で与えられた引数だけで処理をできていないのがダメすぎます。何でしょうこの気持ち悪いwrapperは

 とは言え、前問の答案とスキップ関数を組み合わせれば、このような不快なコードにはなりません。
 しかし、ループを二度も繰り返すのがバカっぽくて嫌でした。

 バカと不快との二択で不快を選びました。不快は馴れますが、バカは治りません。

 次回は、第19問です。今日は満腹だったので見出しは飲み物にしました。

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