我最近一直在做元组和元组列表的大量工作,我一直想知道我是否明智.
对我来说,事情感觉尴尬和笨重,这表明我做错了什么.
例如,我编写了三个便利函数,用于获取3个值的元组中的第一个,第二个和第三个值.
有没有更好的方法让我失踪?
是否有更多通用函数可以组合和操作元组数据?
以下是我想要做的一些事情,感觉应该是一般性的.
提取值:我是否需要为大小为二,三,四和五等的元组创建一个版本的fst,snd等...?
fst3(x,_,_) = x
fst4(x,_,_,_) = x
Run Code Online (Sandbox Code Playgroud)
操作值:你可以在一对列表中递增每个元组的最后一个值,然后使用相同的函数来递增三元组列表中每个元组的最后一个值吗?
压缩和解压缩值:有拉链和拉链3.我还需要一个zip4吗?或者是否有某种方法来创建一般的zip功能?
对不起,如果这似乎是主观的,我老实说不知道这是否可能,或者我每次需要一般解决方案时都浪费时间编写3个额外功能.
感谢您提供任何帮助!
是的,你需要fstN
自己写.但为什么不在模式匹配中提取它呢?
Data.List已经提供了最多zip7
.一般情况下zipN
,使用ZipList.
不是没有扩展.由于所有元组都有不同的类型,因此您必须创建一个类型类,例如:
{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, FunctionalDependencies #-}
class Firstable a b c | a -> b, a -> c where
firstOf :: a -> b
restOf :: a -> c
concatenate :: b -> c -> a
instance Firstable [a] a [a] where
firstOf = head
restOf = tail
concatenate = (:)
instance Firstable (a,b) a b where
firstOf = fst
restOf = snd
concatenate = (,)
instance Firstable (a,b,c) a (b,c) where
firstOf (x,_,_) = x
restOf (_,x,y) = (x,y)
concatenate x (y,z) = (x,y,z)
instance Firstable (a,b,c,d) a (b,c,d) where
firstOf (x,_,_,_) = x
restOf (_,x,y,z) = (x,y,z)
concatenate x (y,z,w) = (x,y,z,w)
instance Firstable (a,b,c,d,e) a (b,c,d,e) where
firstOf (x,_,_,_,_) = x
restOf (_,x,y,z,w) = (x,y,z,w)
concatenate x (y,z,w,t) = (x,y,z,w,t)
Run Code Online (Sandbox Code Playgroud)
然后你可以使用
incFirst :: (Num b, Firstable a b c) => a -> a
incFirst x = (1 + firstOf x) `concatenate` restOf x
main = do
print $ map incFirst [(1,2),(3,4),(5,6)]
print $ map incFirst [(1,3,6,7),(2,5,-2,4)]
Run Code Online (Sandbox Code Playgroud)
(lastOf
很相似.)
但为什么不使用单独的功能?
当我开始拥有大元组时,我使用Haskell的可怜借口来记录语法,为每个元素命名,例如,
data LatticeOperations a = LO { bot :: a
, top :: a
, glb :: a
, lub :: a
, le :: a
}
Run Code Online (Sandbox Code Playgroud)
这是一个五元组,但名称变成了选择单个元素的函数.
对于更改元组,您有记录更新语法.在我刚刚给出的示例中,仅替换一个元素是没有意义的,但我可能会,例如,细化部分顺序并替换三个元素
lattice { le = le', glb = glb', lub = lub' }
Run Code Online (Sandbox Code Playgroud)
当然,如果你有一个很大的记录,并且只是想增加你可以做类似的事情
data FatRecord = FR { count :: Int, ... }
fat = fat { count = count fat + 1 }
Run Code Online (Sandbox Code Playgroud)
我不认为记录语法有助于zip和解压缩.
归档时间: |
|
查看次数: |
7127 次 |
最近记录: |