星田オステオパシー

Racketで何か・・009 連想リスト・Filter・Letrec

じゃあ続きをやっていくか!もちろんLazy racketからLang Racketに乗り換えてからですがね!うーん、Lazy racketに変えてしまったのは多分Haskellとか知る前だったから謙遜して表現してるんだと思ってたのじゃないだろうか・・

describe-path 関数がちゃんと動くか実験、が、動かず!

 なんで? living-roomは繋がりが複数あるので駄目なのか?と、atticでチェックしたけど駄目。色々と試していると


 連想リストになってる部分、解説では対になるリストは「.」でペアにしても良いし普通に半角スペースでも良いということで半角スペースにしてたんだけど、それをドット対にしたらちゃんと動いた。ふーむ


 ところが繋がりが2つあるliving-roomはdescribe-pathsで表示するんだけど、こっちはドット対だと動かず、living-room_(garden_west_door)_(attic_upstairs_ladder) (← _は半角スペース)
 じゃないと逆に動かないと判明。まあ、とりあえず覚えておこう。

続いて
(defun objects-at (loc objs obj-loc) 
  (labels ((is-at (obj)  
           (eq (cadr (assoc obj obj-loc)) loc)))  
     (remove-if-not #'is-at objs)))

 これを訳さないと。LabelsとRemove-if-notが問題だな?

 fletと違ってLabels内で定義した関数をそのまま使えるんでしたよね。これ、今となって見返すと便利ですね!でネットで解説を見るとSchemeでは名前付きLetがそれに当たるんだとか?あれ?けど変数を決めないといかんけど・・?確かLetrecとか言うのがあったような・・


 なんか混乱してきたので一旦元のコードを日本語訳したりする

 苦闘の様子が伺えるコードだ~w Remove-if-notはRacketだとFilterで出来るというのを英語で発見したのでsrfi1をinqureして・・などとやってたけど駄目。結構長時間取り組んでたので、もう何がなんだか分からなくなる。うーん・・どうもエラーメッセージだとリストを渡さないといけないのに真偽値を渡してるような?

 と、ここでもうバイトの時間が近づいてきた!こうなったら・・悔しいけども・・やっちまうか・・

「land of lisp Scheme コード」

 で検索してしまいました(^_^;) したら出てきたんですよねぇまさしくSchemeで翻訳されてるページが。しかも全部ね!あああ・・

 上が僕が書いたけど動かなかったコード。今から考えるとそりゃ動かんて!
 で、下がコピペしてきたコード。って!普通に関数内で関数を作ってfilterそのままかけただけなんかーい!ここで気づきが2つ
 remove-if-notって名前でnot入れないといかんと思ったけど、偽のものを消すってことだから正しいものを残すんだからfilterそのままで良いのか・・
 あと、Filterの便利さに改めて感動する。前に再帰の処理の時には実際にはFilterを使ってなかったから、リスト与えたら全部頭からやってくれるなんて!こりゃ便利だ~(と、今回ようやく本当に分かった)。

 でも・・なんかやっぱり普通にdefineで書けるって納得がいかんなぁ・・とは思ってたんですよね。で、Cametan42さんの対応表をみたところLabelsはLetrecであると。いや、実はスクショ取ってないけど上のLetの代わりにLetrecでも試したんですよね。でも駄目だったんです。

 しかしCametan42さんの備考に気になる一文が。
 「ただしRacket/Schemeではラムダ式を引き連れる

 え?Lambda式で書かんといかんてこと? じゃあまあダメ元でやってみるか・・まあどうせエラーが出るんでしょ?
 って、動いたーっ!!

 今回の分でようやく自分の中にLet,letrec,labels,filterの使い方のリアリティが湧き上がってきた気がする・・ありがとうございます!
 
  • Xでシェアする
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

最近の「プログラミング」カテゴリーもっと見る

最近の記事
バックナンバー
人気記事