繁体   English   中英

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

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

我想将列表 [[1,2,3],[2,3]] 转换为元组 [(1,2,3),(2,3)]

我的 function:

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

这项工作与三个元素。

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)

为什么不这样做?

错误:应用程序中的类型错误* 表达式:两个 x:tupel2 xs 期限:两个x 类型:(a,a) *不匹配:(a,a,a)

好的,让我们跳到最后并启动 ghci。 [(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)]

该错误不是因为我输入的数据错误,而是因为[(1,2,3),(1,2)]不是有效的 haskell。

haskell 中的列表可以包含无限数量的项目,但需要注意的是所有项目必须属于同一类型。

这可能看起来很奇怪,但(1,2,3)(1,2)不是同一类型。 一个是三元组,一个是二元组。

元组与列表有点相反——它只能保存特定数量的项目,但它们可以是一堆不同的类型。 元组类型由它们包含的项目给出的类型序列定义。

所以 3 个整数的元组(或者,正如 ghc 将显示的,类似数字的东西)与 2 个整数的元组具有不同的类型。 我们可以使用 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)

看到(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)

这是因为(2,3,4)(1,2,3)是具有相同类型的两个值。 (1,2)(2,3)也是如此。

所以在 haskell 中没有 function 可以将[[1,2,3],[1,2]]转换为[(1,2,3),(1,2)] ,因为这样的 ZC1C425267 的结果不可能是 E683894F1CAB5A类型检查。

元组有不同的类型,所以没有单一(简单)类型可以给你的tupel

但是,通过退后一步并使用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

请注意我们如何通过模式匹配区分二元素和三元素列表情况。

其次,最好为每个 function 写下您的预期类型——这将有助于解决设计中的混淆,并快速揭示逻辑错误,如两种不同的元组类型。

运行它,您可以看到它如何很好地分组:

*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