【问题标题】:Check if tuple or triple in haskell检查haskell中的元组或三元组
【发布时间】:2018-11-18 21:54:14
【问题描述】:

有没有办法检查(,) 有多少元素?我知道我可以使用fstsnd 访问元组的第一个和第二个元素,但是我认为我可以以某种方式对元素求和,然后将其与 fst 元组 snd 元组进行比较并像这样检查:

tuple = (1,2)

sum tuple == fst tuple + snd tuple

然后我在这种情况下得到 True,而在 triple = (1,2,3) 得到 False。不管怎样我不能问fst (1,2,3) 也不能问sum tuple

有没有办法检查我是否有一个元组?

类似这样的:

is_tuple :: (a,b) -> a
is_tuple (a,_) = a

但是当我输入元组时得到 True,当我给出 (1,2,3) 或 (1,2,3,4) 时得到 False 等等......作为输入。

即:

is_tuple :: Tuple -> Bool
is_tuple x = if x is Tuple 
                then True
                else False

?

【问题讨论】:

  • 您已经在编译时通过类型签名进行了检查。
  • 不,所有各种元组都是不同且不相关的类型。
  • 您不应该只使用列表吗?
  • 这似乎是the XY problem 的一个典型例子。 @cheshire:你到底想完成什么?
  • @cheshire 首先是术语说明:(x,y)(x,y,z) 都是元组。 2 元素元组的词是“pair”。现在,如果您有一个将一对作为参数的函数,并且您尝试使用一对以外的参数调用它,您将得到一个错误 - 在编译时。类型检查已经是一个内置功能。因此,您尝试编写的运行时检查将毫无意义。在您的假设函数返回 false 的情况下,代码一开始就无法编译。

标签: haskell


【解决方案1】:

有没有办法检查(,) 有多少元素?

不,因为答案总是 2。

(,) 类型是两个值的元组或 2 元组的类型构造函数。它与(,,) 不同,后者是三元组的构造函数。同样,这两种类型都不同于(,,,)、4 元组的构造函数等等。

当您编写类型为 (Foo, Bar) -> Baz 的函数时,类型检查器将拒绝任何尝试使用具有不同数量值的元组(或根本不是元组)调用该函数的任何尝试。因此,您的isTuple 函数只有一种逻辑实现,

isTuple :: (a, b) -> Bool
isTuple _ = True

...因为不可能使用不是 2 元组的值实际调用 isTuple

不使用类型类,在 Haskell 中不可能编写一个接受任意大小元组的函数;也就是说,你不能多态超过一个元组的大小。这是因为,与列表不同,元组是异构的——它们可以包含不同类型的值。接受可变长度元组的函数无法预测元组的哪些元素属于哪种类型,因此它实际上无法做任何有用的事情。

极少情况下,在进行高级的类型级技巧时,拥有一个表示可变长度元组的类型会很有用,在 Haskell 中通常称为 HList(对于 异构列表)。这些可以使用花哨的类型类机制和类型级编程实现为库。但是,如果您是初学者,这绝对是不是您想要的。

实际上很难就您应该做什么提供建议,因为正如评论者指出的那样,您的问题类似于an XY problem。考虑提出一个不同的问题,该问题提供了有关您实际尝试解决的问题的更多背景信息,从而使您首先想要找到元组的列表,并且您很可能会得到更多有用的答案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多