我正在讨论这个关于倒计时游戏的 haskell讲座,我不知道任何haskell,但我对这个问题感兴趣,我正试图将他的代码移植到clojure.
这是我卡住的部分必须是我没有进入哈斯克尔的东西,
split :: [a] -> [([a],[a])]
split [] = [([],[])]
split (x:xs) = ([],x:xs) : [(x:ls,rs) | (ls,rs) [([a],[a])]
nesplit = filter ne . split
ne :: ([a],[b]) -> Bool
ne (xs,ys) = not (null xs || null ys)
exprs :: [Int] -> [Expr]
exprs [] = []
exprs [n] = [Val n]
exprs ns = [e | (ls,rs)
我有自己的分裂1 2 3 4它吐出来,
(((1) (2 3 4)) ((1 2) (3 4)) ((1 2 3) (4)))
Run Code Online (Sandbox Code Playgroud)
(defn split [v]
(if (= (count v) 1)
(list (first v))
(map #(list (take % v) (drop % v)) (range 1 (count v)))))
(defn exprs [v]
(if (= (count v) 1)
v
(map #(concat (exprs (first %)) (exprs (second %))) v)))
(exprs (split [1 2 3 4]))
Run Code Online (Sandbox Code Playgroud)
这给了我,
java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.IntegerRun Code Online (Sandbox Code Playgroud)
任何人都可以告诉我我从haskell代码中缺少什么?
他的完整代码清单可在此处获得.
就我有限的 Haskell fu 允许我做的而言,这密切关注 Haskell 的实现......
(defn split
[s]
(map #(split-at % s) (range 1 (count s))))
(defn ne
[s]
(every? (complement empty?) s))
(defn nesplit
[s]
(filter ne (split s)))
(declare combine)
(defn exprs
[s]
(when-let [s (seq s)]
(if (next s)
(for [[ls rs] (nesplit s)
l (exprs ls)
r (exprs rs)
e (combine l r)]
e)
s)))Run Code Online (Sandbox Code Playgroud)
不过还没有测试过。
至于您的错误消息:我认为问题是您没有split在exprs. 然后你会得到1 一个预期的序列......
随机其他注意事项:count序列的时间是线性的。由于我们只需要知道是否有多个元素,因此我们可以检查(next s)against的值nil。