2017-05-06 39 views
2

我正在玩Clojure中的矩阵实现,我正在做这件事,并且学习更多关于Clojure的乐趣,而不是因为我想创建最快的世界上最酷的矩阵实施。修改矢量,以便可以用两个参数调用它

在一个这样的代码所需的主要业务是在一个矩阵给定的行和列,这当然是我写的函数返回值的能力

(mat-getrc m 2 3) 

说“给我矩阵m中第2行第3列的值。完美的Clojure,但详细和。我倒是

(m 2 3) 

当然一个向量)(在我的包矩阵是向量)仅响应一个参数,和B)载体不知道如何使用行和列号来确定正确值的存储位置。

从看the docs for IFn(哪些向量应该实现)看起来存在双参数版本invoke - 但是如何让我的“矩阵”向量实现并响应呢?

任何建议和指向在正确的方向赞赏。

+1

对您而言,“矩阵只是一个常规矢量”属性有多重要?这就是说,对于你来说,修改所有向量的工作方式对你来说真的非常重要,而不是只有一种被认为是矩阵的特定对象(因为你希望它是向量-y,实现了接口['clojure.lang.IPersistentVector'](https:// github。COM/Clojure的/ Clojure的/ BLOB/Clojure的-1.9.0-alpha14/src目录/ JVM/Clojure的/郎/ IPersistentVector.java))? –

+0

如果所有的载体突然开始可以用两个参数调用,它不会打扰我。由于我已经实现了一个矩阵,它看起来像'[[3 2] 1 2 3 4 5 6]',其中索引为零的元素本身是一个表示矩阵中行和列数的二元向量,以下元素是按行优先顺序排列的矩阵的值。今天早些时候,我正在考虑@ChrisMurphy建议的替代实现(例如'[[1 2 3] [4 5 6]'),但考虑到我目前的实施提出了一些有趣的挑战,我想我会坚持下去。 :-) –

+0

@CharlesDuffy:但是,对你的评论进一步跟进,我也不会介意实现一种特定类型的对象作为矩阵。当前实现的吸引力在于“标准”Clojure类型,它的概念是“最好有几种类型和许多对它们进行操作的函数,而不是许多不同的类型,每个函数都有几个函数”。但是,对于我来说这是一个播放时间项目,我愿意接受任何建议。 –

回答

2

您不能修改向量的构建方式,因为它是构建在向量的实现中的,但是您可以定义自己的类型来包装向量,充当向量,并且可以调用deftype。您需要扩展许多与矢量实现相同的接口(但这是一个大的列表):

user=> (ancestors clojure.lang.PersistentVector) 
#{clojure.lang.IEditableCollection clojure.lang.ILookup 
    java.util.concurrent.Callable java.lang.Runnable clojure.lang.IMeta 
    java.lang.Comparable clojure.lang.IReduceInit 
    clojure.lang.IPersistentCollection clojure.lang.IHashEq java.lang.Iterable 
    clojure.lang.IReduce java.util.List clojure.lang.AFn clojure.lang.Indexed 
    clojure.lang.Sequential clojure.lang.IPersistentStack java.io.Serializable 
    clojure.lang.Reversible clojure.lang.Counted java.util.Collection 
    java.util.RandomAccess java.lang.Object clojure.lang.Seqable 
    clojure.lang.Associative clojure.lang.APersistentVector 
    clojure.lang.IKVReduce clojure.lang.IPersistentVector clojure.lang.IObj 
    clojure.lang.IFn} 
+1

万岁!另一个风车!桑乔 - 带出我的长矛! :-)我还没有研究过'deftype' - 我会研究这个。 :-) –

2
(def matrix [[1 2 3 4][5 6 7 8][9 10 11 12]]) 

正如你在你的问题说,这是可能的:

(matrix 2) 

但是,这并不:

(matrix 2 3) 

这将是一个标准的方式来获得一个索引的索引:

(get-in matrix [2 3]) 

您已经可以接近LY得到你想要的,只是多了一些括号:

((matrix 2) 3) 

你可以定义一个高阶函数:

(defn matrix-hof [matrix] 
    (fn [x y] 
    (get-in matrix [x y]))) 

然后把函数,而不是在功能定位矩阵:

(let [m (matrix-hof matrix)] 
    (m 2 3)) 

我不相信你正在问的是使用函数还是宏。

相关问题