【问题标题】:Is there a Haskell equivalent way of iterable unpacking like in Python?是否有类似 Python 的 Haskell 等效的可迭代解包方式?
【发布时间】:2020-06-03 21:01:53
【问题描述】:

我想知道是否可以从 Haskell 中的可迭代事物中创建变量。我在搜索时找到了this,但我无法根据我的情况调整它。也许这是不可能的,或者因为我是初学者,所以我错过了一些东西。基本上,我想知道在 Haskell 中是否有可能:

>>> list_of_lists = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> a, b, c = list_of_lists
>>> print(a)
[1, 2, 3]

【问题讨论】:

  • 可以解压,例如let [a, b, c] = [[1,2,3], [4,5,6], [7,8,9]] in a。然而,它并没有什么“特别”,就像在 Python 中一样,它是简单的模式匹配。对于大多数可折叠产品(如TreeMaybe 等),您可以使用toList
  • 它被称为pattern matching,除了列表之外,它适用于许多数据类型。

标签: python haskell iterable-unpacking


【解决方案1】:
ghci> list_of_lists = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
ghci> [a,b,c] = list_of_lists
ghci> print a
[1,2,3]

【讨论】:

    【解决方案2】:

    luqui 给出的答案在列表恰好包含三个元素时有效。然而,它是部分的,这意味着它在运行时对于任何其他大小的列表都会失败。

    我认为,一个更惯用的 Haskell 解决方案应该是这样的函数:

    listToTriple :: [a] -> Maybe (a, a, a)
    listToTriple [a, b, c] = Just (a, b, c)
    listToTriple _ = Nothing
    

    您可以使用任意长度的列表安全地调用它:

    *Q62157846> listToTriple [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
    Just ([1,2,3],[4,5,6],[7,8,9])
    *Q62157846> listToTriple [[1, 2, 3], [4, 5, 6]]
    Nothing
    *Q62157846> listToTriple [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
    Nothing
    

    如果在第一种情况下,您只需要这三个列表中的第一个,则可以对三元组进行模式匹配:

    *Q62157846> fmap (\(a, _, _) -> a) $ listToTriple [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
    Just [1,2,3]
    

    【讨论】:

    • 我实际上确信我的列表将恰好包含 3 个元素,因此不会对这种情况造成任何问题。但我也在想,如果列表的大小未知,我将如何进行。所以这绝对有帮助,感谢您的澄清!
    • @Asocia 如果你确定你正好有三个元素,那么使用三元组(,,) 会比使用列表更好。
    • 我非常犹豫在这里推荐元组。因为它们通常是异构的,所以当用作同构容器时,它们提供的功能远不如列表方便。事实上,我倾向于说元组应该在将两个未知的、可能不同类型的元素组合在一起时使用。老实说,列表可能是最明智的解决方案。当然,一些类型保证会很好,但 Haskell 不是一门完整的语言,而且它通常是不可行的。 (虽然如果IsString 类有一个额外的Nat 参数,它应该实际上是可行的。)
    • @leftaroundabout 可以定义data Triple a = Triple a a a,然后...
    • ...或使用库之一,例如Linear.V3
    猜你喜欢
    • 2012-08-26
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    • 2019-03-07
    • 1970-01-01
    • 2010-10-10
    • 1970-01-01
    • 2012-01-21
    相关资源
    最近更新 更多