这个函数使用了另一个在函数式编程中很常用的技术:高阶函数.apply和map这两个函数能将其它的函数作为参数.map函数将另一个函数分别作用到list中的每个对象上,这里是调用describe-path函数.apply concat是为了减少多余的括号,没有多少功能性操作!我们来试试新函数
(spel-print (describe-paths 'living-room game-map))user=> (spel-print (describe-paths 'living-room game-map))
(there is a door going west from here -
there is a stairway going upstairs from here -)
漂亮!
最后,我们还剩下一件事要做:描述某个地点的某个对象!我们先写个帮助函数来告诉我们在某个地方是否有某个对象!
(defn is-at? [obj loc obj-loc] (= (obj obj-loc) loc))
=也是个函数,它判断对象的地点是否和当前地点相同!
我们来尝试一下:
(is-at? 'whiskey-bottle 'living-room object-locations)user=> (is-at? 'whiskey-bottle 'living-room object-locations)
true
返回结果是true,意味着whiskey-bottle在起居室.
现在让我们来使用这个函数描述地板:
(defn describe-floor [loc objs obj-loc]
(apply concat (map (fn [x]
`(you see a ~x on the floor -))
(filter (fn [x]
(is-at? x loc obj-loc)) objs))))
这个函数包含了很多新事物:首先,它有匿名函数(fn定义的函数).第一个fn干的事,和下面的函数做的事情是一样的:
(defn blabla [x] `(you see a ~x on the floor.))
(spel-print (describe-floor 'living-room objects object-locations))user=> (spel-print (describe-floor 'living-room objects object-locations))
(you see a whiskey-bottle on the floor - you see a bucket on the floor -)
现在,让我们来将这些函数串联起来,定义一个叫look的函数,使用全局变量(这个函数就不是函数式的了!)来描述所有的内容:
(defn look []
(spel-print (concat (describe-location location game-map)
(describe-paths location game-map)
(describe-floor location objects object-locations))))
我们来试一下:
user=> (look)
(you are in the living room of a wizards house -
there is a wizard snoring loudly on the couch -
there is a door going west from here -
there is a stairway going upstairs from here -
you see a whiskey-bottle on the floor -
you see a bucket on the floor -)
本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/shumachanpin/article-41579-4.html
超喜欢千玺
人
我有点好奇