2011-09-19 105 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))))))