Has*_*hin 3 haskell tuples list
我有一个元组列表.每个元组也是一个元组.对于每个外部元组,我有一个共轭元组.我的意思是,如果我在列表中有(a,b),那么我也有(b,a).我想要的是从列表中删除共轭元组.
为了给你一个我列表的具体例子,它是:
[((1,2,1,0),(5,2,1,0)),((2,4,4,0),(2,5,4,0)),((2,5,4,0),(2,4,4,0)),((3,1,1,0),(3,3,2,0)),((3,3,2,0),(3,1,1,0)),((5,1,7,0),(8,1,7,0)),((5,2,1,0),(1,2,1,0)),((5,5,8,0),(8,5,8,0)),((5,6,6,0),(8,6,8,0)),((5,9,9,0),(8,9,9,0)),((6,3,5,0),(6,8,9,0)),((6,8,9,0),(6,3,5,0)),((7,7,6,0),(9,7,6,0)),((8,1,7,0),(5,1,7,0)),((8,5,8,0),(5,5,8,0)),((8,6,8,0),(5,6,6,0)),((8,9,9,0),(5,9,9,0)),((9,7,6,0),(7,7,6,0))]
删除共轭元组后的结果应为:
[((1,2,1,0),(5,2,1,0)),((2,4,4,0),(2,5,4,0)),((3,1,1,0),(3,3,2,0)),((5,1,7,0),(8,1,7,0)),((5,5,8,0),(8,5,8,0)),((5,6,6,0),(8,6,8,0)),((5,9,9,0),(8,9,9,0)),((6,3,5,0),(6,8,9,0)),((7,7,6,0),(9,7,6,0)),]
我已经尝试了几个小时没有成功.任何帮助将不胜感激.
首先,我们可以将类型概括为以下内容:
nubTuples :: Eq a => [(a,a)] -> [(a,a)]
Run Code Online (Sandbox Code Playgroud)
但是,为了使事情变得高效和简单,我们还要求一个Ord实例a.为什么这会让事情变得更容易?因为现在我们可以将元组转换为有序的正规形式.那我们可以简单nub . sort.下面的实现实际上只是基于该表示进行排序和结点,所以nubTuples [(2,1)] = [(2,1)]不是[(1,2)].
import Data.List (sortOn, nubBy)
import Data.Tuple (swap)
nubTuples :: Ord a => [(a,a)] -> [(a,a)]
nubTuples = nubBy unorderedCompare . sortOn orderTuple
where orderTuple (x,y)
| x < y = (x,y)
| otherwise = (y,x)
unorderedCompare x y = x == y || swap x == y
Run Code Online (Sandbox Code Playgroud)
请注意,这会更改顺序并删除重复项:
nubTuples [(3,4),(1,2),(1,2)] = [(1,2),(3,4)]
Run Code Online (Sandbox Code Playgroud)
至于改变的订单,我们可以通过使用修复此nubWith功能从Data.Discrimination在discrimination包中.然后我们的代码将变为以下内容:
import Data.Discrimination (nubWith, Grouping)
nubTuples :: (Ord a, Grouping a) => [(a,a)] -> [(a,a)]
nubTuples = nubWith orderTuple
where orderTuple (x,y)
| x < y = (x,y)
| otherwise = (y,x)
Run Code Online (Sandbox Code Playgroud)
这不需要排序,保持订单完整并且最大程度上是懒惰的(这通常对性能非常重要).它仍然删除重复.
您可以简单地Grouping为您的任何类型派生一个实例,如下所示:
{-# LANGUAGE DeriveGeneric #-}
import Data.Discrimination
import GHC.Generics
data A = A deriving Generic
instance Grouping A
Run Code Online (Sandbox Code Playgroud)
请注意,没有Grouping4元组的实例.这将是一种解决它的方法:
nubFourTuples :: (Grouping a, Ord a, Grouping b, Ord b,
Grouping c, Ord c, Grouping d, Ord d)
=> [((a,b,c,d),(a,b,c,d))] -> [((a,b,c,d),(a,b,c,d))]
nubFourTuples = (fmap . both) reassociate . nubTuples . (fmap . both) associate
where associate (w,x,y,z) = ((w,x),(y,z))
reassociate ((w,x),(y,z)) = (w,x,y,z)
both f (x,y) = (f x, f y)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
92 次 |
| 最近记录: |