2011-09-19 112 views
2

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

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

有没有其他解决方案?

+4

也许你可以解释一下使用称为“set-difference”的函数来找出两组差异的问题。你究竟想要什么? –

+0

看着这些编辑,我认为z_axis可能意味着他的“集合差异”加法是解决他的问题。我认为克里斯摩根的帮助尝试可能会掩盖这种意图。 – JasonFruit

+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) 
3

我不知道Common Lisp中那么好,所以这里有一个方案的实施由Ben粘贴代码:

(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 1,而receive来自SRFI 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))))))