2013-10-08 105 views
-2

我一直在围绕Haskell进行编码,但无法掌握实现联合函数的想法。 我也发现了一些嵌入Haskell平台的函数定义。但问题是我需要一个简洁易懂的方式才能使它工作。 任何人都可以帮助我吗?Haskell中的联合函数

+0

具体哪个联合功能? – bheklilr

+0

@bheklilr两组整数之间的联合。你能帮我吗? –

+0

你想要实际组合?你看过'Data.Set'吗?在'Set's上有一个'union'函数。 – bheklilr

回答

6

假设你正在谈论union :: Eq a => [a] -> [a] -> [a]这需要两个输入列表,并返回一个包含了所有每个参数列表元素的第三列表,那么它在Data.List这是在base包中定义。

在它分成两个函数的源,广义功能unionBy这需要平等且然后(类型等于(==) :: a -> a -> Bool的函数)的一个自定义的定义定义了通过在(==)传递作为具体使用Eq类型类的一个实行平等。

union     :: (Eq a) => [a] -> [a] -> [a] 
union     = unionBy (==) 

我们可以替代(==)unionBy代码,但是,作为Haskell允许我们用等式推理。

union = unionBy (==) 

-- so... 

union  :: Eq a => [a] -> [a] -> [a] 
union xs ys = xs ++ foldl (flip (deleteBy (==))) (nubBy (==) ys) xs 

此相同的图案在deleteBynubBy,这两者遵循相同的惯例,unionBy定义发生两次以上。 delete从列表中移除一个元素,nub返回一个唯一元素列表。我们将再次简化定义以消除(==)的所有痕迹,并简单地假定元素a已定义Eq

union xs ys = xs ++ foldl (flip delete) (nub ys) xs 

现在定义可能更具可读性。 xsysunionxs附加到已由foldl (flip delete) _ xs处理的ys的唯一(“nub床”)值。 foldl的最终结果就是一个一个尝试到delete的每个元素xs(nub ys)。这意味着union xs ysxs附加到ys中的每个独特元素少于xs中的那些元素。


顺便说一句,与此源在手,我们可以看到的union一些古怪的行为,例如如何在第一个参数从所述第二参数

union [1,1,2] [2] == [1,1,2] 
union [2] [1,1,2] == [2,1] 

这是有点对待重复不同的结果是使用[]来表示Set类似union的概念。但是,如果我们使用Set.fromList查看结果,那么我们很好。

xs, ys :: Eq a => [a] 
Set.fromList (xs `union` ys) == Set.fromList xs `Set.union` Set.fromList ys 

这也给我们的union

union xs ys = Set.toList (Set.fromList xs `Set.union` Set.fromList ys) 

那么另一个定义请问是怎么foldl伎俩工作?让我们解开foldl的定义来查看,再次滥用等式推理。

union xs ys = xs ++ (case xs of 
    []  -> nub ys 
    (x:xs') -> foldl (flip delete) (delete x (nub ys)) xs' 
) 

这将使超过xs元素特技更加明显,它的循环,从(nub ys)删除它们一个接一个。


虽然希望这有助于使代码union更清晰一点,真正带回家应该是均分的推理是解剖Haskell代码的强大工具。不要害怕通过手动内嵌函数的定义来直接简化代码。

+0

谢谢,但我只是要求提供简单的信息。我觉得我现在很迷茫...... –

+0

@mehdix_直觉:从'ys'删除'xs'的所有元素,然后执行'xs ++ stripedDownYs'。这就是联盟所做的。删除部分只需要折叠 – jozefg

+0

@jozefg更简单:只需使用(++) – Ingo