F#中的Haskell列表差异运算符

8
在F#中是否有类似于Haskell的列表差分操作符\\的等效操作符?
5个回答

5

不是这样的...只需编写并将其设置为中缀运算符-使用特殊字符集。反斜杠(\)不在以下列表中,因此它不能用作中缀运算符。请参见手册

infix-op :=

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

**OP

prefix-op :=

!OP ?OP ~OP -OP +OP % %% & &&

5
“// will work as an infix operator”并不是一个中缀运算符。这是F#中的单行注释。 - J D

5

我之前被弹出了,但我认为在这里写出(/-/)的实现是值得的(这是Haskell中\\的F#版本):

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]

2

从减数集合中筛选项目:

let ( /-/ ) xs ys =
    let ySet = set ys
    let notInYSet x = not <| Set.contains x ySet
    List.filter notInYSet xs

1
我正在使用这个:


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

如果有人看到问题,请告诉我。
这是用于列表的,所以结果中可能会有重复项。例如:
[1;1;2] /-/ [2;3] would be eq to [1;1]

-2
假设你确实想要传统的集合差异而不是Haskell提供的奇怪的有序但未排序的多重集合减法,只需使用内置的set函数将列表转换为集合,然后使用内置的-运算符计算集合差异:
set xs - set ys

例如:

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

1
@Jon 我想这将取决于你的基础模型是袋子还是集合。 - ScottWest
Haskell的函数对于集合也不太适用,因为它要求按顺序进行操作(必须删除第一次出现的元素)。 - J D
2
该函数适用于列表,因此有一个顺序。它更加具体的事实使其成为包操作的细化。 - ScottWest
袋子很重要,因为袋子差分运算符更好地描述了你试图实现的差分运算符,而不是集合差分运算符。 - ScottWest
2
啊,我说过这是一个袋操作的完善。也就是说,如果你将袋实现为列表,你可以使用列表的//运算符,并且它将成为袋差运算符的实现。同样,++将成为袋和运算符的实现。有序性只是更多信息,它不会影响袋接口(因为它无论如何都不知道)。 - ScottWest
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接