首页 文章

lein run和REPL之间的行为不一致

提问于
浏览
0

我是clojure的新手,并尝试通过解决https://www.4clojure.com中的问题来学习它 . 任务是实现展平功能 . 这是我的实施:

(ns clojure-noob.core                                                           
  (:gen-class))                                                                 

(defn -main                                                                     
  "I don't do a whole lot ... yet."                                             
  []                                                                            
  (= ((fn [coll]                                                                
        (let [flat (fn [coll]                                                   
                     (when-let [s (seq coll)]                                   
                       (if (sequential? (first s))                              
                         (concat (flat (first s)) (flat (rest s)))              
                         (cons (first s) (flat (rest s))))))]                   
          (flat coll)))                                                         
      '((1 2) 3 [4 [5 6]]))                                                     
     '(1 2 3 4 5 6)))

当我在REPL中运行它时(-main)我得到了真的 .

当我以lein run运行它时,我得到了这个异常:

线程“main”中的异常java.lang.RuntimeException:无法在此上下文中解析符号:flat,在clojure.lang.Compiler.analyze上编译:(clojure_noob / core.clj:11:42)(Compiler.java:6688)在clojure.lang.Compaly.analyze(Compiler.java:6625)的clojure.lang.Comparse $ InvokeExpr.parse(Compiler.java:3766)在clojure的clojure.lang.Compiler.analyzeSeq(Compiler.java:6870) . lang.Compiler.analyze(Compiler.java:6669)位于clojure.lang.Compaly上的clojure.lang.Compaly.analyze(Compiler.java:6625),clojure.lang.Compiler $ InvokeExpr.parse(Compiler.java:3834) .analyzeSeq(Compiler.java:6870)位于clojure.lang.Compaly.analyze(Compiler.java:6669)的clojure.lang.Compiler.analyze(Compiler.java:6625),位于clojure.lang.Compiler $ IfExpr $ Parser . 在clojure.lang.Compaly.analyze(Compiler.java:6669)的clojure.lang.Compaly.analyze(Compiler.java:6669)的clojure.lang.Compaly.analyze(Compiler.java)中解析(Compiler.java:2797) :6625)at clojur.lang.Compiler $ BodyExpr $ Parser.parse(Compiler.java:6001)at clojur e.lang.Compiler $ LetExpr $ Parser.parse(Compiler.java:6319)at clojure.lang.Compaly.analyzeSeq(Compiler.java:6868)at clojure.lang.Compiler.analyze(Compiler.java:6669)at clojure .lang.Compiler.analyzeSeq(Compiler.java:6856)at clojure.lang.Compaly.analyze(Compiler.java:6669)at clojure.lang.Compiler.analyze(Compiler.java:6625)at clojure.lang.Compiler $ BodyExpr $ Parser.parse(Compiler.java:6001)位于clojure.lang.Compaly.analyze(Compiler.java:6868)的clojure.lang.Compaly.analyze(Compiler.java:6669),来自clojure.lang.Compiler.analyze (Compiler.java:6625)位于clojure.lang.Compaly.analyze的clojure.lang.Compaly.analyzeSeq(Compiler.java:6868)的clojure.lang.Compiler $ IfExpr $ Parser.parse(Compiler.java:2797) Compiler.java:6669)在clojure.lang.Compaly.analyze(Compiler.java:6856)的clojure.lang.Compaly.analyze(Compiler.java:6669)clojure.lang.Compiler.analyze(Compiler.java:6625) )在clojure.lang.Compiler $ BodyExpr $ Parser.parse(Compiler.java:6001)的clojure.lang.Compiler $ LetExpr $ Parser . 解析(Compiler.java:6319)位于clojure.lang.Compaly.analyzeSeq(Compiler.java:6868)的clojure.lang.Compiler.analyze(Compiler.java:6669)clojure.lang.Compiler.analyzeSeq(Compiler.java) :6857)在clojure.lang.Compaly.analyze(Compiler.java:6669)的clojure.lang.Compaly.analyzeSeq(Compiler.java:6856)的clojure.lang.Compiler.analyze(Compiler.java:6669)at clojure .lang.Compiler.analyze(Compiler.java:6625)at clojure.lang.Compiler $ BodyExpr $ Parser.parse(Compiler.java:6001)at clojure.lang.Compiler $ FnMethod.parse(Compiler.java:5380)at at clojure.lang.Compiler $ FnExpr.parse(Compiler.java:3972)位于clojure.lang.Compaly.analyzeSeq(Compiler.java:6866)的clojure.lang.Compiler.analyze(Compiler.java:6669)clojure.lang .jiler.analyzeSeq(Compiler.java:6856)at clojure.lang.Compiler.analyze(Compiler.java:6669)at clojure.lang.Compiler.access $ 300(Compiler.java:38)at clojure.lang.Compiler $ LetExpr $ parser.parse(Compiler.java:6269)位于clojure.lang上的clojure.lang.Compiler.analyzeSeq(Compiler.java:6868) .compiler.analyze(Compiler.java:6669)在clojure.lang.Compaly.analyzeSeq(Compiler.java:6856)的clojure.lang.Compiler.analyze(Compiler.java:6669)的clojure.lang.Compiler.analyze( Compiler.java:6625)在clojure.lang.Compiler $ BodyExpr $ Parser.parse(Compiler.java:6001)的clojure.lang.Compiler $ FnMethod.parse(Compiler.java:5380)at clojure.lang.Compiler $ FnExpr .parse(Compiler.java:3972)在clojure.lang.Compaly.analyzeSeq(Compiler.java:6866)的clojure.lang.Compiler.analyze(Compiler.java:6669)的clojure.lang.Compiler.analyzeSeq(编译器 . java:6856)at clojure.lang.Compaly.analyze(Compiler.java:6669)at clojure.lang.Compaly.analyze(Compiler.java:6625)at clojure.lang.Compiler $ InvokeExpr.parse(Compiler.java:3766) )clojure.lang.Compaly.analyzeSeq(Compiler.java:6870)at clojure.lang.Compaly.analyze(Compiler.java:6669)at clojure.lang.Compiler.analyze(Compiler.java:6625)at clojure.lang . 编译器$ HostExpr $ Parser.parse(Compiler.java:1009)at clojure.lang.Compiler.analyzeSeq(Compiler.java:686 8)在clojure.lang.Compaly.analyze(Compiler.java:6669)的clojure.lang.Compiler.analyze(Compiler.java:6625)的clojure.lang.Compiler.analyzeSeq(Compiler.java:6863)at atclojure.lang.Compiler.analyze(Compiler.java:6669)at clojure.lang.Compaly.analyze(Compiler.java:6625)at clojure.lang.Compiler $ BodyExpr $ Parser.parse(Compiler.java:6001)at clojure .lang.Compiler $ FnMethod.parse(Compiler.java:5380)at clojure.lang.Comparse(Compiler.java:3972)位于clojure的clojure.lang.Compiler.analyzeSeq(Compiler.java:6866) . lang.Compiler.analyze(Compiler.java:6669)at clojure.lang.Compaly.analyzeSeq(Compiler.java:6856)at clojure.lang.Compaly.analyze(Compiler.java:6669)at clojure.lang.Compiler.access在clojure.lang.Compaly.analyze的clojure.lang.Compaly.analyzeSeq(Compiler.java:6868)上的clojure.lang.Compiler $ DefExpr $ Parser.parse(Compiler.java:589)$ 300(Compiler.java:38) (Compiler.java:6669)在clojure.lang.Compaly.analyze(Compiler.java:6625)的clojure.lang.Compiler.eval(Compiler.java:6931)的clojure.lang.Compiler.load(Compiler.java: 7379)在clojure上的clojure.lang.RT.loadResourceScript(RT.java:372)的clojure.lang.RT.loadResourceScript(RT.java:363) . lang.RT.load(RT.java:453)at clojure.core $ load $ fn__5677.invoke(core.clj:5893)在clojure.core $ load的clojure.lang.RT.load(RT.java:419) .invokeStatic(core.clj:5892)at clojure.core $ load.doInvoke(core.clj:5876)at clojure.lang.RestFn.invoke(RestFn.java:408)at clojure.core $ load_one.invokeStatic(core . clj:5697)at clojure.core $ load_one.invoke(core.clj:5692)at clojure.core $ load_lib $ fn__5626.invoke(core.clj:5737)at clojure.core $ load_lib.invokeStatic(core.clj:5736) )clojure.core $ load_lib.doInvoke(core.clj:5717)at clojure.core(RestFn.java:142)at clojure.core $ apply.invokeStatic(core.clj:648)at clojure.core $ load_libs.invokeStatic(core.clj:5774)at clojure.core $ load_libs.doInvoke(core.clj:5758)at clojure.lang.RestFn.applyTo(RestFn.java:137)at clojure.core $ apply.invokeStatic( core.clj:648)at clojure.core $ require.invokeStatic(core.clj:5796)at clojure.core $ require.doInvoke(core.clj:5796)at clojure.lang.RestFn.invoke(RestFn.java:408) )在用户$ eval1036 $ fn__1038.invoke(form-ini t8418556840412273777.clj:1)用户$ eval1036.invokeStatic(form-init8418556840412273777.clj:1)at user $ eval1036.invoke(form-init8418556840412273777.clj:1)at clojure.lang.Compiler.eval(Compiler.java:6927) )clojure.lang.Compiler.eval(Compiler.java:6917)at clojure.lang.Compiler.load(Compiler.java:7379)at clojure.lang.Compiler.loadFile(Compiler.java:7317)at clojure.main $ load_script.invokeStatic(main.clj:275)at clojure.main $ init_opt.invokeStatic(main.clj:277)at clojure.main $ init_opt.invoke(main.clj:277)at clojure.main $ initialize.invokeStatic( main.clj:308)at clojure.main $ null_opt.invokeStatic(main.clj:342)at clojure.main $ null_opt.invoke(main.clj:339)at clojure.main $ main.invokeStatic(main.clj:421) )clojure.main $ main.doInvoke(main.clj:384)at clojure.lang.RestFn.invoke(RestFn.java:421)at clojure.lang.Var.invoke(Var.java:383)at clojure.lang .AFn.applyToHelper(AFn.java:156)at clojure.lang.Var.applyTo(Var.java:700)at clojure.main.main(main.java:37)引起:java.lang.RuntimeExce ption:无法解析符号:flat在此上下文中的clojure.lang.Util.runtimeException(Util.java:221)中的clojure.lang.Compiler.resolveIn(Compiler.java:7164)中的clojure.lang.Compiler.resolve( Compiler.java:7108)在clojure.lang.Compaly.analyzeSymbol(Compiler.java:7069)的clojure.lang.Compiler.analyze(Compiler.java:6648)... 128更多

我怀疑它与名称空间有关,但我不知道如何解决它 .

1 回答

  • 1

    flat 的let绑定中,您可以参考 flat ,这是不可见的 . fn 有一个可选的名称参数,您可以使用它来解决此问题 .

    (defn -main                                                                     
      "I don't do a whole lot ... yet."                                             
      []                                                                            
      (= ((fn [coll]                                                                
            (let [flat (fn flat [coll]                                              
                         (when-let [s (seq coll)]                                   
                           (if (sequential? (first s))                              
                             (concat (flat (first s)) (flat (rest s)))              
                             (cons (first s) (flat (rest s))))))]                   
              (flat coll)))                                                         
          '((1 2) 3 [4 [5 6]]))                                                     
         '(1 2 3 4 5 6)))
    

    此外,代码可以显着简化而不改变含义:

    (defn -main                                                                     
      "I don't do a whole lot ... yet."                                             
      []                                                                            
      (let [flat (fn flat [[el & els :as coll]]                                     
                   (when coll                                                       
                     (if (sequential? el)                                           
                       (concat (flat el) (flat els))                                
                       (cons el (flat els)))))]                                     
        (= (flat [[1 2] 3 [4 [5 6]]])                                               
           [1 2 3 4 5 6])))
    

相关问题