我在Python之后学习Haskell,并且我认为创建一个函数可以找到序列中不在另一个序列中的所有项目(其中两个序列都具有可以比较的元素)将是一个有趣的运动。我在Python中轻松地为此编写了一些代码:
def inverse(seq, domain):
ss = iter(seq)
dd = iter(domain)
while True:
s = next(ss)
while True:
d = next(dd)
if d != s:
yield d
if d >= s:
break
(seq
和domain
都已排序)
但是,我努力将此代码转换为Haskell。我认为我只使用列表(可能是无限的)而不是ss
和dd
,我想我使用s = next(ss)
与{{s = head ss
相同1}}和ss = tail ss
,但我无法弄清楚我是如何将其转化为Haskell的。我也无法解决我对两个while
循环所做的事情。我认为我可以使用无限递归,但由于有两个循环,我不知道这是否需要两个函数或什么。
答案 0 :(得分:6)
我无法让你的代码按照宣传的方式工作,但我认为这个代码段应该与你的代码大致相同,有两个假设:X和Y是排序的,所有元素都是唯一的。
我们要从xx
中删除yy
中的所有元素。在每个步骤中,我们只需要在函数定义中比较每个元素的第一个元素(x
和y
)。那么可能会发生三件事:
x
小于y
,这意味着x
不在yy
,因此我们可以接受x
x
等于y
,我们拒绝x
x
大于y
,这意味着我们需要在yy
前进,才能确定是拒绝还是接受x
这是函数定义:
minus :: Ord a => [a] -> [a] -> [a]
minus xx@(x:xs) yy@(y:ys) = case (compare x y) of
LT -> x : minus xs yy
EQ -> minus xs ys
GT -> minus xx ys
minus xs _ = xs