是否有一种优雅的方式来创建和使用具有常量和概率字段的记录.我希望能够做类似下面的事情,其中"sampler"是一个从某个分布返回样本的函数.目标是使用户无论访问的字段是常量还是概率都是透明的.
> (defrecord Stat [val1 val2])
> (def s1 (Stat. 1 sampler))
> (:val1 s1)
> 1
> (:val2 s1)
> 4
> (:val2 s1)
> 2
Run Code Online (Sandbox Code Playgroud)
对于自定义deftypes,关键字查找的行为可能不仅仅是在地图中查找固定值,但我强烈建议不要使用它.它不仅需要做很多工作,还会违背每个人阅读代码的期望.
但是,稍微调整一下您的要求就可以得到一个简单的解决方案:而不是(:val1 x)写(x :val1).现在x可以简单地成为一个函数,它让它接收的输入决定了它的行为:
user> (defn stat [distributions]
(fn [sample]
((get distributions sample))))
#'user/stat
user> (def s1 (stat {:val1 (constantly 1)
:val2 #(rand-int 5)}))
#'user/s1
user> (s1 :val1)
1
user> (s1 :val2)
3
user> (s1 :val2)
4
Run Code Online (Sandbox Code Playgroud)
定义的记录的查找行为defrecord无法更改.deftype提供更多控制,但实现所有正确的接口需要一些工作.意识到,potemkin可以让您轻松定义具有自定义行为的类似地图的事物:
(use '[potemkin :only [def-map-type]])
(def-map-type Stat [val1 val2]
(get [_ k default-value]
(case k
:val1 val1
:val2 (val2)
default-value)))
(def s1 (->Stat 1 #(rand-int 10)))
(:val1 s1) ; => 1
(:val2 s1) ; => something in [0, 9]
(get s1 :val2) ; => something in [0, 9]
Run Code Online (Sandbox Code Playgroud)
您也可以定义assoc,dissoc以及keys但是他们有意义的数据.
| 归档时间: |
|
| 查看次数: |
151 次 |
| 最近记录: |