Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
处理haskell元组的好函数和技术?_Haskell_Types - Fatal编程技术网

处理haskell元组的好函数和技术?

处理haskell元组的好函数和技术?,haskell,types,Haskell,Types,我最近做了很多关于元组和元组列表的工作,我一直在想我是否明智 事情让我感到尴尬和笨拙,这对我来说意味着我做错了什么 例如,我编写了三个方便函数,用于获取3个值的元组中的第一个、第二个和第三个值 有没有更好的方法让我错过 是否有更通用的函数允许您编写和操作元组数据 以下是我正在尝试做的一些事情,这些事情应该是可以推广的 提取值: 我需要创建fst、snd等的版本吗。。。对于大小为2、3、4和5的元组,等等 fst3(x,_,_) = x fst4(x,_,_,_) = x 操纵值: 您可以增加成

我最近做了很多关于元组和元组列表的工作,我一直在想我是否明智

事情让我感到尴尬和笨拙,这对我来说意味着我做错了什么

例如,我编写了三个方便函数,用于获取3个值的元组中的第一个、第二个和第三个值

有没有更好的方法让我错过

是否有更通用的函数允许您编写和操作元组数据

以下是我正在尝试做的一些事情,这些事情应该是可以推广的

提取值: 我需要创建fst、snd等的版本吗。。。对于大小为2、3、4和5的元组,等等

fst3(x,_,_) = x
fst4(x,_,_,_) = x
操纵值: 您可以增加成对列表中每个元组的最后一个值,然后使用相同的函数增加三元组列表中每个元组的最后一个值吗

压缩和解压缩值: 有一个拉链和一个拉链。我也需要拉链吗?或者有没有办法创建一个通用的zip函数

抱歉,如果这看起来很主观,我真的不知道这是否可能,或者每次我需要一个通用的解决方案时,我是否在浪费时间编写3个额外的函数


谢谢你能给予的任何帮助

如果不使用模板Haskell之类的扩展,就无法概括元组大小。所以,如果我们只考虑Haskell:是的,你确实需要编写<代码> fST <代码>等版本。对于每个元组大小,不,你不能编写一般的zip方法。

提取值 是的,您需要自己编写
fstN
。但是为什么不在模式匹配中提取呢

压缩和解压缩值 已提供多达
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)
那你可以用

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)]
lastOf
类似。)


但是为什么不使用单独的函数呢?

Haskell内置的
fst
snd
只支持元组对,所以您可以定义自己的元组对。如果要增加列表中的最后一个值,请反转列表,从该端开始工作,然后将其反转回来。如果希望该增量适用于列表和元组列表,只需定义一个新函数,该函数将为这些数据类型进行增量,并在列表的增量函数中调用该函数@肯尼特回答了zipN的问题


在Haskell中使用列表和元组与许多语言有点不同,但经过一段时间后,它们相比起来感觉特别自然和强大。

一旦元组的大小超过3左右,和/或相同的元组类型得到广泛使用,最好使用记录。

当我开始使用大元组时,我使用Haskell的记录语法的可怜借口为每个元素命名,例如

data LatticeOperations a = LO { bot :: a
                              , top :: a
                              , glb :: a
                              , lub :: a
                              , le  :: a
                              }
这是一个五元组,但是名称变成了选择单个元素的函数

对于更改元组,您有记录更新语法。在我刚刚给出的示例中,只替换一个元素是没有意义的,但是我可以,例如,改进偏序并替换三个元素

lattice { le = le', glb = glb', lub = lub' }
当然,如果你有一个大的记录,只是想增加你可以做一些事情,如

data FatRecord = FR { count :: Int, ... }

fat = fat { count = count fat + 1 }
我不认为记录语法有助于压缩和解压缩。

我最近发现 {-#语言记录通配符} 允许记录将字段选择器用作值- 这样地: 数据R=R{a::Int,b::String,c::Bool}

testA R{..}=a>0

或 .. = R{..}式中a=7;b=“x”;c=真


检查GHC手册

迟到总比不迟到好:试试。

对不起,我不清楚我的意思(我已经更正了这个问题)。我的意思不是:你能增加成对列表的最后一个值,然后用同样的函数增加三元组列表的最后一个值吗?我的意思是:你能增加成对列表中每个元组的最后一个值,然后使用相同的函数增加三元组列表中每个元组的最后一个值吗?抱歉搞混了!创建5+个函数来做完全相同的事情对我来说似乎是浪费。(并不是说我在必要时做这件事有任何问题)。也许我只是喜欢非常干燥的东西。我想可能做得太过分了。无耻的插拔:
Firstable
Secondable
Thirdable
<代码>n表!这是因为元组的每个大小都是不同的类型。在类型系统中不可能只说“一个元组”,因为没有这样的类型-有对、3元组和4元组,它们都是不同的东西。