首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >不能将clojure.lang.Cons转换为Clojure.lang.Ifn

不能将clojure.lang.Cons转换为Clojure.lang.Ifn
EN

Stack Overflow用户
提问于 2018-04-05 22:02:13
回答 1查看 1.7K关注 0票数 1

大家好,我最近试着学习一种新的语言,我遇到了Clojure,它看上去很有趣,因为我从来没有听说过函数式编程,尽管我在使用JavaScript之前就使用过它,好吧,我不再讨论这个问题了。

我一直致力于解决https://github.com/gigasquid/wonderland-clojure-katas,并更具体地解决了双打问题。我想我已经有了一个解决方案,但它给我带来了这篇文章标题上的错误。我读过关于这个错误的文章,当您想让编译器期望一个函数时,它似乎会触发,但它不需要。下面是我的解决方案的完整代码,看看您是否可以帮助我解决这个问题:

代码语言:javascript
复制
(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)))

正如您所看到的,can是一个函数,因此错误似乎不是上面描述的情况。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-04-05 22:12:49

我可以在下载words.edn文件并使用(doublets "bank" "loan")运行后再现错误。我认为问题在于这些表达方式:

代码语言:javascript
复制
 (% 0)

在几个地方都有。我看到你是cons-ing的一些东西,所以这可能是一个线索。(% 0)应该做什么?如果您想要第一个字符,只需说(first xyz)或其他什么。

我还会公开匿名函数#(...)并给它们取实名。

更新

我的猜测似乎是正确的,因为这个实验表明:

代码语言:javascript
复制
(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

好吧,重写如下:

代码语言:javascript
复制
(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

代码语言:javascript
复制
(def words (-> "words.edn"
             (io/resource)
             (slurp)))

我们现在在这一行上得到了一个新的错误:

代码语言:javascript
复制
    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,然后尝试使用(count \f)。你不能数一个字符,只有一个字符串。

我会让你从那里调试它。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49682209

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档