【问题标题】:Haskell list comprehension with tuple input带有元组输入的 Haskell 列表理解
【发布时间】:2023-04-10 11:00:01
【问题描述】:

是否有可能以某种方式使用元组作为列表理解的输入?或者可能是元组理解?我希望以下内容可以工作,但事实并非如此。

[x * 2 | x <- (4, 16, 32)]

我不能从一开始就使用列表,因为我的作业函数的给定签名是

success :: (Int, Int, Int) -> Int -> (Int, Int, Int) -> Bool

但是使用列表会简单得多,因为其中一部分任务需要我计算元组中有多少 1s 和 20s。

【问题讨论】:

    标签: haskell tuples list-comprehension


    【解决方案1】:

    Control.Lens 重载了对所有长度的同构元组的遍历支持:

    import Control.Lens
    
    -- Convert to list:
    (3, 4, 5)^..each -- [3, 4, 5]
    (1, 2)^..each -- [1, 2]
    
    -- modify elements:
    (4, 16, 32)& each %~ \x -> x * 2 -- (8, 32, 64)
    (1, 2)& each %~ (+1) -- (2, 3)
    
    -- operator notation for common modifications (see Control.Lens.Operators):
    (1, 2, 3)& each +~ 2 -- (3, 4, 5)
    (1, 2, 3)& each *~ 2 -- (2, 4, 6)
    
    -- monadic traversals (here each works like `traverse` for the list monad)
    each (\x -> [x, x + 1]) (1, 2) -- [(1,2),(1,3),(2,2),(2,3)]
    
    -- `each` is basically an overloaded "kitchen sink" traversal for 
    -- common containers. It also works on lists, vectors or maps, for example
    [(3, 4), (5, 6)]& each . each +~ 1 -- [(4, 5), (6, 7)]
    

    【讨论】:

      【解决方案2】:

      您可以创建一个函数将三元组转换为列表:

      tripleToList :: (a, a, a) -> [a]
      tripleToList (a, b, c) = [a, b, c]
      

      那你就可以了

      [x * 2 | x <- tripleToList (4, 16, 32)]
      

      【讨论】:

      • 有没有办法为两到五个元素的元组重载函数toList
      • 如果你做了很多 - Tuple -> List 反之亦然 - 你很可能做错了什么或非常不习惯。
      • @Niklas:您可以使用类型类来定义一个通用函数 toList,然后为每个元组的重载创建实例。使用-XMultiParamTypeClasses-XFlexibleInstancesclass ToList t l where toList :: t -&gt; [l]instance ToList (a,a,a) a where toList (a,b,c) = a:b:c:[]instance ToList (a,a,a,a) a where toList (a,b,c,d) = a:b:c:d:[]
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-26
      • 2015-07-24
      • 2014-02-24
      • 2021-01-12
      • 1970-01-01
      相关资源
      最近更新 更多