関数の中にはtest引数を持っているものがある。test引数は関数のふるまいを定義するものである。例えば、ソートするときの比較ルールとか、リストから要素を削除する条件など。
このtestは主にラムダ関数で定義する。
このtestは主にラムダ関数で定義する。
例:リスト内の重複要素を削除する
remove-dup関数は、リスト内で同じ要素を削除する関数。要素を2つずつ全ての組み合わせでチェックして同じだったら片方削除するというような感じ。
#ref error :画像を取得できませんでした。しばらく時間を置いてから再度お試しください。
- 引数[0]はリスト。
- 引数[1]はテスト関数。これが消す条件を設定するところ。デフォルトでは'eql。値はLisp eql関数で比較される。比較の結果がt(真偽値のtrue)ならば削除対象として消される。イコールにもいろいろ種類があるがそれはまた別のページで。
#ref error :画像を取得できませんでした。しばらく時間を置いてから再度お試しください。
上例のremove-dup関数が重複している6300を1つ削除している。
別のテスト関数を定義する
音高リストからオクターブ重複も含めて削除したいとする。しかしOMにそんな関数はない。どうするか?
これはremove-dup関数のテスト関数をいじれば実現可能。いま問題となっているのは、デフォルトのeq関数では6000(C4)と7200(C5)は同一の値と判断されてない、つまりeq関数では偽を返すので削除されないことである。6000と7200を新しいテスト関数で比較してt(真偽値のtrue)を返すことができれば、「これは削除対象だ」とremove-dup関数が判断して消してくれる。
思い出せ:1オクターブは1200セント。
これはremove-dup関数のテスト関数をいじれば実現可能。いま問題となっているのは、デフォルトのeq関数では6000(C4)と7200(C5)は同一の値と判断されてない、つまりeq関数では偽を返すので削除されないことである。6000と7200を新しいテスト関数で比較してt(真偽値のtrue)を返すことができれば、「これは削除対象だ」とremove-dup関数が判断して消してくれる。
思い出せ:1オクターブは1200セント。
#ref error :画像を取得できませんでした。しばらく時間を置いてから再度お試しください。
このパッチはom//関数を使ってオクターブ関係も同一とみなす関数の試作品である。
今6400(F#4)と7600(F#5)が比較されている。
om//のアウトプット[0]は割り算の商を、アウトプット[1]は余りを出力する。
1200で割った余りはそれぞれ400、400でom=で比較すればt(真)が返る。
余りとオクターブ関係
1200で割った余りでオクターブ関係を判断するこの関数はうまくいきそうである。
C4 : (6000 / 1200) = 5 あまり 0
C5 : (7200 / 1200) = 6 あまり 0
C4 : (6000 / 1200) = 5 あまり 0
C5 : (7200 / 1200) = 6 あまり 0
F#4 : (6400 / 1200) = 5 あまり 4
F#5 : (7600 / 1200) = 6 あまり 4
F#5 : (7600 / 1200) = 6 あまり 4
関数のふるまいを変える
試作品をいじってきちんとしたテスト関数にする。
内部パッチを作って(図の赤いアイコン)その中を「インプットを2つあげたらオクターブ関係を含めた重複を判断して同じ音なら真をアウトプット」という形に組む。
この重複判定関数mypatchをremove-dup関数のtest引数にラムダモードでつなぐ。
そうしてremove-dup関数を評価するとうまいことオクターブ重複も消える。
内部パッチを作って(図の赤いアイコン)その中を「インプットを2つあげたらオクターブ関係を含めた重複を判断して同じ音なら真をアウトプット」という形に組む。
この重複判定関数mypatchをremove-dup関数のtest引数にラムダモードでつなぐ。
そうしてremove-dup関数を評価するとうまいことオクターブ重複も消える。
#ref error :画像を取得できませんでした。しばらく時間を置いてから再度お試しください。