Оператор разницы в списке Хаскелла в F # - PullRequest
8 голосов
/ 12 сентября 2008

Есть ли эквивалентный оператор оператору разницы в списках Хаскелла \\ в F #?

Ответы [ 5 ]

4 голосов
/ 15 сентября 2012

Отскочил, но я считаю, что стоит написать здесь реализацию ( /-/ ) (F #-версия Haskell's \\):

let flip f x y = f y x

let rec delete x = function
  | [] -> []
  | h :: t when x = h -> t
  | h :: t -> h :: delete x t

let inline ( /-/ ) xs ys = List.fold (flip delete) xs ys

Это будет работать как Haskell \\, так что (xs @ ys) /-/ xs = ys. Например: (7 :: [1 .. 5] @ [5 .. 11]) /-/ [4 .. 7] оценивается в [1; 2; 3; 5; 7; 8; 9; 10; 11].

4 голосов
/ 12 сентября 2008

Нет ... Просто напишите это и сделайте это инфиксным оператором - используя набор специальных символов. Обратная косая черта (\) отсутствует в списке ниже, поэтому она не будет работать как оператор инфикса. См. руководство :

infix-op: =

or || & && <OP >OP $OP = |OP &OP ^OP :: -OP +OP *OP /OP %OP

**OP

prefix-op: =

!OP ?OP ~OP -OP +OP % %% & &&
1 голос
/ 22 мая 2011

Фильтр элементов из набора вычитаемых:

let ( /-/ ) xs ys =
    let ySet = set ys
    let notInYSet x = not <| Set.contains x ySet
    List.filter notInYSet xs
0 голосов
/ 15 января 2015

Я использую это:

let (/-/) l1 l2 = List.filter (fun i -> not <| List.exists ((=) i) l2) l1

Если кто-нибудь увидит проблему, дайте мне знать.

Для списков, поэтому в результате могут быть дубликаты. Например:

[1;1;2] /-/ [2;3] would be eq to [1;1]
0 голосов
/ 06 мая 2009

Предполагая, что вы действительно хотите обычную разность наборов, а не странное упорядоченное, но несортированное многосетевое вычитание, которое, по-видимому, обеспечивает Haskell, просто преобразуйте списки в наборы, используя встроенную функцию set, а затем используйте встроенную - оператор для вычисления заданной разности:

set xs - set ys

Например:

> set [1..5] - set [2..4];;
val it : Set<int> = seq [1; 5]
...