简体   繁体   English

在 Haskell 中将各种长度的列表转换为元组

[英]Convert various length of List to Tuple in Haskell

I want convert list [[1,2,3],[2,3]] to tuple [(1,2,3),(2,3)]我想将列表 [[1,2,3],[2,3]] 转换为元组 [(1,2,3),(2,3)]

my function:我的 function:

thr [a,b,c] = (a,b,c)
tupel [] = []
tupel (x:xs) = if length x==3 then thr x:(tupel xs) else (tupel xs)

this work with three Elements.这项工作与三个元素。

thr [a,b,c] = (a,b,c)
two [a,b]   = (a,b)
tupel [] = []
tupel (x:xs) = if length x==3 then thr x:(tupel xs) else two x:(tupel xs)

why don´t work this?为什么不这样做?

Error: Type error in application * Expression: two x: tupel2 xs错误:应用程序中的类型错误* 表达式:两个 x:tupel2 xs Term: two x期限:两个x Type: (a,a) * Does not match: (a,a,a)类型:(a,a) *不匹配:(a,a,a)

Ok, let's skip to the end and fire up ghci.好的,让我们跳到最后并启动 ghci。 What type does [(1,2,3),(1,2)] have? [(1,2,3),(1,2)]有什么类型?

ghci> :t [(1,2,3),(1,2)]

<interactive>:1:10:
     Couldn't match expected type `(t0, t1, t2)'
                 with actual type `(t3, t4)'
     In the expression: (1, 2)
     In the expression: [(1, 2, 3), (1, 2)]
     In an equation for `it': it = [(1, 2, 3), (1, 2)]

That error isn't because I entered the data wrong, it's because [(1,2,3),(1,2)] isn't valid haskell.该错误不是因为我输入的数据错误,而是因为[(1,2,3),(1,2)]不是有效的 haskell。

A list in haskell can hold an unlimited number of items, with the caveat that all items must be of the same type. haskell 中的列表可以包含无限数量的项目,但需要注意的是所有项目必须属于同一类型。

It may seem weird, but (1,2,3) and (1,2) aren't of the same type.这可能看起来很奇怪,但(1,2,3)(1,2)不是同一类型。 One is a 3-tuple, one is a 2-tuple.一个是三元组,一个是二元组。

A tuple is sort of the opposite of a list - it can only hold a specific number of items, but they can be of a bunch of different types.元组与列表有点相反——它只能保存特定数量的项目,但它们可以是一堆不同的类型。 Tuple types are defined by the sequence of types given by the items they contain.元组类型由它们包含的项目给出的类型序列定义。

So a tuple of 3 integers (or, as ghc will show, number-like things) is of different type than a tuple of 2 integers.所以 3 个整数的元组(或者,正如 ghc 将显示的,类似数字的东西)与 2 个整数的元组具有不同的类型。 We can see this directly using the :t operator in ghci:我们可以使用 ghci 中的:t运算符直接看到这一点:

ghci> :t (1,2,3)
(1,2,3) :: (Num t1, Num t2, Num t) => (t, t1, t2)
ghci> :t (1,2)
(1,2) :: (Num t1, Num t) => (t, t1)

See that (2,3,4) and (2,3) have types that match (1,2,3) and (1,2) 's respectively:看到(2,3,4)(2,3)具有分别匹配(1,2,3)(1,2)的类型:

ghci> :t (2,3,4)
(2,3,4) :: (Num t1, Num t2, Num t) => (t, t1, t2)
ghci> :t (2,3)
(2,3) :: (Num t1, Num t) => (t, t1)

That's because (2,3,4) and (1,2,3) are two values that have the same type.这是因为(2,3,4)(1,2,3)是具有相同类型的两个值。 The same is true for (1,2) and (2,3) . (1,2)(2,3)也是如此。

So there is no function to convert [[1,2,3],[1,2]] to [(1,2,3),(1,2)] in haskell because the result of such a function could not possibly type-check.所以在 haskell 中没有 function 可以将[[1,2,3],[1,2]]转换为[(1,2,3),(1,2)] ,因为这样的 ZC1C425267 的结果不可能是 E683894F1CAB5A类型检查。

Tuples have different types, so there's no single (simple) type to give to your tupel function.元组有不同的类型,所以没有单一(简单)类型可以给你的tupel

However, by stepping back and using a sum type you can encode all the variants you wish to return:但是,通过退后一步并使用sum 类型,您可以对您希望返回的所有变体进行编码:

data T a
    = One   a
    | Two   a a
    | Three a a a
    deriving Show

two :: [a] -> T a
two [a,b]   = Two   a b

thr :: [a] -> T a
thr [a,b,c] = Three a b c

tuple :: [[a]] -> [T a]
tuple []           = []
tuple ([a,b]  :xs) = Two   a b   : tuple xs
tuple ([a,b,c]:xs) = Three a b c : tuple xs
tuple (_ : xs)     =               tuple xs

Note how we distinguish between the two and three-element list case via pattern matching.请注意我们如何通过模式匹配区分二元素和三元素列表情况。

And secondly, it is good practice to write down your expected type for each function -- this will help resolve confusion in the design, and quickly reveal logical errors like the two different tuple types.其次,最好为每个 function 写下您的预期类型——这将有助于解决设计中的混淆,并快速揭示逻辑错误,如两种不同的元组类型。

Running this, you can see how it groups things nicely:运行它,您可以看到它如何很好地分组:

*Main> tuple [[1,2,3],[2,3]] 
[Three 1 2 3,Two 2 3]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM