【问题标题】:How do I "unpack" a list as individual arguments in Haskell? [duplicate]如何在 Haskell 中将列表“解包”为单个参数? [复制]
【发布时间】:2015-12-09 18:43:15
【问题描述】:

Haskell 中是否有内置或惯用的方法来“解包”列表的元素并将它们视为函数的单独参数?

例如,如果我有 f :: a -> b -> c -> d -> e 是否有类似的紧凑的东西

f (unlist x)

完成

let x = [1,2,3,4] in f (x!!0) (x!!1) (x!!2) (x!!3) 

或者至少是一种不那么“喧哗”(!! 重复次数过多)的方式来解压缩一个已知长度的列表(在这种情况下,它可以用作函数的参数)。


基本上我正在寻找的东西类似于 Sequence@@ 在 Mathematica 中所做的:

f[Sequence@@{1, 2, 3, 4}]

【问题讨论】:

  • 我认为这不会在 Haskell 的类型系统中进行类型检查。可能有unlist1unlist2unlist3 等变体。在这种情况下,unlist3 f [a, b, c] = f a b c 并使用unlist3 f x 或使用中缀看起来像一个函数“调用”。
  • a trick说服类型系统让你编写多变量函数。它是相对重要且重量级的,因此您不会经常看到它。最著名的用例是Text.Printf

标签: haskell syntax functional-programming parameter-passing


【解决方案1】:

它在 Haskell 类型系统中不是特别有用:

  1. 正如 Mephy 所指出的,您需要为每个列表长度设置一个单独的函数,并且当传递长度错误的列表时,它会在运行时失败;
  2. 所有参数都必须具有相同的类型。

鉴于此,使用元组比使用列表更有意义,因为它避免了这两个问题;标准库包括uncurry,它为2个参数的函数执行此操作,您可以通过类比定义uncurry3等:

uncurry3                 :: (a -> b -> c -> d) -> ((a, b, c) -> d)
uncurry3 f (a, b, c)     =  f a b c

【讨论】:

  • 有没有办法解决我幼稚的做法,让它看起来不像我在大喊大叫(里面有很多!!!!!!!!!s!)?
  • 这很好,但一般来说,除非有必要,否则尽量避免使用!!。例如。使用模式匹配而不是 !! 来访问已知小索引处的元素:let [a, b, c, d] = [1,2,3,4] in f a b c d
  • @raxacoricofallapatorius ... 在大多数情况下,要访问 large 已知索引处的元素,您应该切换到不同的数据结构,因为 (!!),除了部分是也 O(n) 在索引中。
  • @AlexeyRomanov:我喜欢这种方法,但它对我不起作用。如果我用readsPrec _ s = [(f c w s r, "")] where [c, w, s, r] = words s 替换readsPrec _ s = [(f (x!!0) (x!!1) (x!!2) (x!!3), "")] where x = words s(效果很好;f 进行验证),执行就会挂起。不知道我在那里缺少什么。
  • @raxacoricofallapatorius,你重用了变量名s...
猜你喜欢
  • 1970-01-01
  • 2020-01-13
  • 1970-01-01
  • 2012-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-24
  • 1970-01-01
相关资源
最近更新 更多