Clojure和html表单 - clojure.lang.LazySeq无法强制转换为clojure.lang.IFn

时间:2015-05-30 14:57:27

标签: exception casting clojure

我有以下问题:当我在REPL中键入函数时,每个工作正常并且我没有得到任何异常,但是当我从html中的输入字段获取我的clojure函数的输入值时,我得到了clojure .lang.LazySeq无法转换为我的代码的这部分的clojure.lang.IFn异常:

{{1}}

输入值是从输入字段中正确获取的,所以不是问题......有没有人知道问题是什么? 谢谢你的建议,我对clojure中的clojure和web编程很新。

2 个答案:

答案 0 :(得分:0)

缩进代码有助于揭示部分错误。不幸的是,你还没有说明你想要完成什么,所以很难提供完整的答案。我想做一些猜测,我认为即使我猜错了,我说的也会帮助你理清问题。

@bsvingen是对的,那是一个缺少的括号。但是,我的猜测是问题是在第一个nth之前有一个额外的括号。您不希望=申请包含nth的两个表达式吗?它没有。相反,第一个被评估,Clojure期望它生成一个函数,因为它出现在列表的开头。如果我们解决了这个问题,结果是:

(apply map + 
       (for [i (range (count frequencies-of-words-reviews))]
         (for [j (range (count tokens))]
           (if (= (nth frequencies-of-words-reviews i)
                  (nth tokens j))
             nil)
             0
             1)))

但是,这可能不是你想要的,因为在这种情况下,如果条件为真,if表达式返回nil,如果条件为假,{{1 }" else"的默认值是返回if。所以nil表达式无论如何都返回nil。但是,无论如何都会忽略此值,if也是如此。我重写的代码是为每个元素返回0。所以这不是你想要的。

接下来,您不需要两个1。你可以使用

for

我的猜测是,您尝试使用(for [i ... j ...] ...) 进行测试的是=的密钥是否等于frequencies-of-words-reviews中的字符串,以及您是否[&1;}重新尝试计算你获得平等的情况。在这种情况下,代码看起来像这样,在第4行添加了tokens

keys

(注意,我能够跟踪所有括号并确保它们是正确的唯一方法是让我的编辑器格式化代码。当得到的缩进不正确时,我知道我做错了什么。)

然而,仍然存在问题。您将(apply map + (for [i (range (count frequencies-of-words-reviews)) j (range (count tokens))] (if (= (nth (keys frequencies-of-words-reviews) i) (nth tokens j)) 0 1))) 定义为第一个元素是哈希映射的列表。这通常会产生错误,因为Clojure假定列表的第一个元素是一个函数。但是,事实证明哈希映射也被视为函数,因此没有错误,但结果是frequencies-of-words-reviews具有值frequencies-of-words-reviews。解决方案是引用列表:

nil

或使用矢量:

(def frequencies-of-words-reviews
  '({"charging" 1, "excellent" 2, "bit" 1, "great" 1}, {"bought" 1, "daughter" 1}))

你需要对(def frequencies-of-words-reviews [{"charging" 1, "excellent" 2, "bit" 1, "great" 1}, {"bought" 1, "daughter" 1}])

做同样的事情
tokens

但是,根据我的猜测,我认为你需要合并两个哈希映射。如果它们具有一些相同的键,则需要一些小心。 (def tokens ["charging" "excellent" "bit" "great" "bought" "daughter"]) 可能对此有用。我只想合并两张地图:

merge-with

最后,如果您尝试对结果值求和,那么您不需要(def frequencies-of-words-reviews (merge {"charging" 1, "excellent" 2, "bit" 1, "great" 1}, {"bought" 1, "daughter" 1})) ,则需要apply map +apply +。结果是:

reduce +

这总结了一堆0和1,并产生结果30。

其他提示:

避免将索引编入索引会更加惯用。查看(apply + (for [i (range (count frequencies-of-words-reviews)) j (range (count tokens))] (if (= (nth (keys frequencies-of-words-reviews) i) (nth tokens j)) 0 1)) filtersome

答案 1 :(得分:0)

最直接的问题是这部分:

((nth frequencies-of-words-reviews i)...

调用函数" nth"将返回一个值,我将调用X.然后你会得到类似的东西:

(X (nth tokens j))

其中clojure试图将X解释为函数(在JVM中实现为接口clojure.lang.IFn)。

第一次通过循环,索引我将成为地图{"充电" 1,"优秀" 2," bit" 1,"伟大" 1}。虽然这可能与您的意图相同或不同,但它似乎与例外相符。

如果您可以粘贴一个工作的5行示例并将其粘贴到此处,我们可以快速解决问题。现在,我怀疑你在编辑器中拥有的内容以及你在REPL中粘贴的内容或者在这里略有不同。