2

在 haskell 中,[1,2,3,4,5,6,7] \\ [4,5,6]将返回[1,2,3,7]. 现在我想使用 clisp 实现相同的功能。到目前为止,我找到了set-difference作品:

(set-difference '(1 2 3 4 5 6 7) '(4 5 6))

还有其他解决方案吗?

4

2 回答 2

3

这是haskell库源代码的相关部分。也许你可以直接翻译这些定义。我不认为它使用任何特定于 Haskell 的东西。

(来源来自http://haskell.org/ghc/docs/latest/html/libraries/base/src/Data-List.html

删除 :: (Eq a) => a -> [a] -> [a]
删除 = deleteBy (==)

-- | 'deleteBy' 函数的行为类似于 'delete',但需要一个
-- 用户提供的相等谓词。
deleteBy :: (a -> a -> Bool) -> a -> [a] -> [a]
删除 _ _ [] = []
deleteBy eq x (y:ys) = if x `eq` y then ys else y : deleteBy eq x ys

(\\) :: (Eq a) => [a] -> [a] -> [a]
(\\) = foldl(翻转删除)
于 2011-09-19T06:55:11.220 回答
3

我不太了解 Common Lisp,所以这是 Ben 粘贴的代码的 Scheme 实现:

(define (difference big small)
  (fold delete big small))

(define (delete x lst)
  (delete-by equal? x lst))

(define (delete-by equal? x lst)
  (if (null? lst) '()
      (receive (y ys) (car+cdr lst)
        (if (equal? x y) ys
            (cons y (delete-by equal? x ys))))))

从哪里来foldcar+cdrSRFI 1来,receiveSRFI 8来。


如果我们允许自己使用SRFI 26cut形式,那么我们有一个看起来更接近 Haskell 版本的解决方案(因为后者至少在两个地方使用了柯里化):

(define difference (cut fold delete <...>))
(define delete (cut delete-by equal? <...>))

; Unchanged from the above version
(define (delete-by equal? x lst)
  (if (null? lst) '()
      (receive (y ys) (car+cdr lst)
        (if (equal? x y) ys
            (cons y (delete-by equal? x ys))))))
于 2011-09-19T07:12:21.163 回答