Clojure解构与Haskell样式的参数模式匹配

3

作为一个来自Haskell的人,我发现在Clojure中遍历一些数据类型很困难。 在Haskell中,如果我想对某个类型进行递归,最基本的情况下通常是这样的:

foo (x : [])     = Just value
foo (x : y : xs) = bar y (foo xs)
foo _            = Nothing

很好。

但是我认为Clojure的解构远不如Haskell的模式匹配强大。有没有一种漂亮的惯用方式来完成我要做的事情?举个例子,如果我有一个列表/向量,如何匹配没有更多元素的情况?


@octopusgrabbus 这是什么样的纠正? - ayan ahmedov
2个回答

8
你可以使用 core.match,如果需要。
例如,
(defn foo [v] 
  (match v 
    [x] x
    [x y & more] (+ (* x y) (foo more)) 
    :else nil))

它是否被广泛使用,还是我在Clojure中寻找一种不必要的模式? - ayan ahmedov
@ayanahmedov 它经常被使用但并不广泛,或者如果你愿意的话,它不是一种惯用语。模式匹配和解构之间的主要区别在于,模式匹配关注严格的结构和分派,而解构关注松散的结构。它们的目的不同。 - cgrand
1
使用频率对于一个刚从 beta 版本中毕业的库来说,是一个不太好的衡量有用性的标准。 - A. Webb

0

正如A. Webb所说,您可以使用core.match以模式匹配的方式编写。不过,只使用原始函数也可以相当容易地编写此类代码:

(defn foo [[x y & xs]]
  (cond
    (and x y) (bar y (foo xs))
    x         x
    :else     nil))

你的代码假设 nil 和 false 不是序列的合法值。 - cgrand
@cgrand:没错。将它适应到那种情况并不难,但我认为我们谈论的是一般形式而不是特定情况。 - Chuck

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接