大家好,我最近一直试图学习一门新语言,而且我碰到了Clojure,它看起来像一个真正有趣的语言,因为我从来没有听说过函数式编程,即使我曾经使用过在那之前使用JavaScript之类的JavaScript,我会停止谈论并解决问题。
我一直致力于解决https://github.com/gigasquid/wonderland-clojure-katas问题,更具体地解决双重问题。我想我已经找到了一个解决方案,但它发送给我这篇文章标题的错误。我已经阅读了这个错误,似乎它会在您希望编译器需要一个函数时触发,但它没有。以下是我的解决方案的完整代码,看看你是否可以帮我解决这个问题:
(ns doublets.solver
(:require [clojure.java.io :as io]
[clojure.edn :as edn]
[clojure.set :as set]))
(def words (-> "words.edn"
(io/resource)
(slurp)
(read-string)))
(defn linked-word [word word-list]
(some #(when (= (count (set/difference (into #{} (seq %))
(into #{} (seq word)))) 1) %)
word-list))
(defn doublets [word1 word2]
(let [n (count word1) v (cons word1 (filter #(= (count %) n)
(remove #{word1} words)))]
(tree-seq #(and (linked-word (% 0) %) (not= (% 0) word2))
#(cons (linked-word (% 0) (rest %))
(remove #{(% 0)} (rest %))) v)))
正如您所看到的,cons是一个函数,因此错误似乎是上述情况。
任何帮助将不胜感激。 谢谢你提前!!!!
答案 0 :(得分:3)
我可以在下载words.edn
文件并使用(doublets "bank" "loan")
运行后重现错误。我认为问题在于这些表达方式:
(% 0)
你在几个地方。我看到你是cons-ing
一些东西,所以这可能是一个线索。什么是(% 0)
应该做的?
如果你想要第一个字符,只需说出(first xyz)
或其他内容。
我还会打破匿名函数#(...)
并给它们真实姓名。
我的猜测似乎是正确的,因为这个实验显示:
(cons 1 [2 3]) => (1 2 3)
(class (cons 1 [2 3])) => clojure.lang.Cons
(vec (cons 1 [2 3])) => [1 2 3]
(class (vec (cons 1 [2 3]))) => clojure.lang.PersistentVector
好的,重写如下:
(defn doublets [word1 word2]
(let [n (count word1)
v (vec (cons word1 (filter #(= (count %) n)
(remove #{word1} words))))]
(tree-seq
#(and
(linked-word (% 0) %)
(not= (% 0) word2))
#(vec (cons (linked-word (% 0) (rest %)))
(remove #{(% 0)} (rest %)))
v)))
新错误:java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol
我们需要的是线索!
我们正在评估符号,而不是字符串!问题是read-string
,这是您阅读 源代码 的方式,而不是字符串之类的数据。删除read-string
:
(def words (-> "words.edn"
(io/resource)
(slurp)))
我们现在在这一行上收到一个新错误:
v (vec (cons word1 (filter #(= (count %) n)
(remove #{word1} words))))]
ERROR in (dotest-line-40) (RT.java:664)
Uncaught exception, not in assertion.
expected: nil
actual: java.lang.UnsupportedOperationException:
count not supported on this type: Character
因此,您的seq
创建了类似“foo”=>的内容[\ f \ o \ o],然后你试着说(count \f)
。您不能计算单个字符,只能计算字符串。
我会让你从那里调试它。