【问题标题】:How to implement the haskell `\\` function?如何实现haskell `\\` 功能?
【发布时间】:2011-09-19 06:49:33
【问题描述】:

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

还有其他解决办法吗?

【问题讨论】:

  • 也许你可以解释一下使用一个叫做“set-difference”的函数来找出两个集合的差异有什么问题。你到底想要什么?
  • 查看编辑,我认为 z_axis 可能意味着他的set-difference 添加是解决他的问题的方法。我认为 Chris Morgan 的帮助可能掩盖了这一意图。
  • 我不习惯将列表视为集合。

标签: haskell lisp set clisp


【解决方案1】:

这里是相关的 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(翻转删除)

【讨论】:

    【解决方案2】:

    我不太了解 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 1,而receive 来自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))))))
    

    【讨论】:

      猜你喜欢
      • 2020-07-31
      • 2021-11-23
      • 2023-03-22
      • 2021-04-15
      • 1970-01-01
      • 1970-01-01
      • 2020-03-24
      • 2022-07-04
      • 2021-01-08
      相关资源
      最近更新 更多