如何实现haskell` \\`函数?

时间:2011-09-19 06:49:33

标签: haskell lisp set clisp

在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))

还有其他解决方案吗?

2 个答案:

答案 0 :(得分:3)

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

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

delete                  :: (Eq a) => a -> [a] -> [a]
delete                  =  deleteBy (==)

-- | The 'deleteBy' function behaves like 'delete', but takes a
-- user-supplied equality predicate.
deleteBy                :: (a -> a -> Bool) -> a -> [a] -> [a]
deleteBy _  _ []        = []
deleteBy eq x (y:ys)    = if x `eq` y then ys else y : deleteBy eq x ys

(\\)                    :: (Eq a) => [a] -> [a] -> [a]
(\\)                    =  foldl (flip delete)

答案 1 :(得分: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+cdr来自SRFI 1receive来自SRFI 8


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

(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))))))