【发布时间】:2013-11-30 10:45:15
【问题描述】:
我正在尝试为一个类项目建模一个 L 系统,但在使用了几个月的 Clojure 之后,我正在努力使用 Scala 的 reduce/fold 和类型系统来实现这一目标。
在 Clojure 中,我会写
user> (defn update-state [translation-map, state]
(mapcat #(get translation-map %1 [%1]) state))
user> (def translations {"a" ["b", "a", "b"]})
user> (update-state translations ["a"])
["b", "a", "b"]
这个技巧有效,因为我隐式定义了(update-state "b") => ["b"],并且我使用clojure.core/mapcat 来处理concat 一起翻译的值。
因此,如果我们两次应用此操作,我们会看到示例 L 系统的行为符合预期..
user> (->> ["a"]
(update-state translations)
(update-state translations))
["b", "b", "a", "b", "b"]
我的 Scala 尝试是
package me.arrdem.planter;
import scala.collection.mutable.{HashMap,LinkedList};
class LSystem[keytype,fntype] {
var _invoke_map = HashMap[keytype,fntype]()
var _tr_map = HashMap[keytype,Seq[keytype]]()
def translate(s:Seq[keytype], k:keytype) : Seq[keytype] = {
s ++ (if(_tr_map contains(k)) _tr_map.get(k) else (k))
}
def step(s:Seq[keytype]) : Seq[keytype] = {
s foldRight(LinkedList[keytype]())(translate)
}
}
在我看来,除了类型检查器抱怨之外,这应该可以工作
ERROR: type mismatch; found : Seq[Any] required: Seq[keytype] : line 9
ERROR: type mismatch; found : keytype required: scala.collection.GenTraversableOnce[?] : line 9
ERROR: type mismatch; found : keytype required: scala.collection.GenTraversableOnce[?] : line 9
现在,当我读到这篇文章时,隐含的错误是表达式(if(_tr_map contains(k)) _tr_map.get(k) else (k)) 被类型推断为Seq[Any] 而不是Seq[keytype]。
由于两个结果是 1) 找到密钥 -> Seq[keytype] 和 2) 未找到密钥 -> 单例元组 (k),这怎么可能,我该如何纠正?
干杯
【问题讨论】: