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))
他の解決策はありますか?
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))))))
どこでとfold
SRFI 1car+cdr
から来て、SRFI 8から来ます。receive
SRFI 26の形式を使用できるようにするcut
と、Haskell バージョンにさらに近いソリューションが得られます (後者は少なくとも 2 か所でカリー化を使用しているため)。
(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))))))
haskell ライブラリ ソースの関連部分を次に示します。これらの定義を直接翻訳できるかもしれません。Haskell に固有のものは何も使用していないと思います。
(ソースはhttp://haskell.org/ghc/docs/latest/html/libraries/base/src/Data-List.htmlから)
delete :: (Eq a) => a -> [a] -> [a] 削除 = deleteBy (==) -- | 「deleteBy」関数は「delete」のように動作しますが、 -- ユーザー提供の等価述語。 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 (フリップ削除)