【问题标题】:Haskell Performing fst on a 3 part tupleHaskell 在 3 部分元组上执行 fst
【发布时间】:2013-03-28 14:00:07
【问题描述】:

我有以下 Haskell 元组:

       [("string",1,1)]

我需要提取其中的第一个元素,显然在这里使用 'fst' 不起作用,因为有 3 个组件。

最好的使用方法是什么? sel?

【问题讨论】:

标签: haskell


【解决方案1】:

sel可以通过以下方式使用:

$ cabal install tuple
$ ghci
>>> :m +Data.Tuple.Select
>>> sel1 ("string",1,1)
"string"

它与map 的任何其他功能一样工作

>>> map sel1 [("One",1,0),("Two",2,0),("Three",3,0)]
["One","Two","Three"]

主要优点是它适用于更大的元组

>>> sel1 ("string",1,1,1)
"string"

以及标准元组

>>> sel1 ("string",1)
"string"

因此无需单独处理。


更多示例:

>>> map sel2 [("One",1,0),("Two",2,0),("Three",3,0)]
[1,2,3]
(0.06 secs, 4332272 bytes)
>>> map sel3 [("One",1,0),("Two",2,0),("Three",3,0)]
[0,0,0]
(0.01 secs, 2140016 bytes)
>>> map sel4 [("One",1,0),("Two",2,0),("Three",3,0)]

<interactive>:6:5:
.... error

【讨论】:

  • 是的,对于所有大小小于 15 的元组(定义了 sel15 但没有 sel16)。
  • 此限制是由于 ghc tupe 限制有关更多信息,请参阅stackoverflow.com/questions/2978389/haskell-tuple-size-limit
  • 我不会认为tuple 已死,只是稳定。
  • 好吧,我想说不再维护,反正我要删除我的考虑,因为它似乎是不正确的。
  • 今天(2021 年)运行cabal install tuple 给了我警告:您要求安装可执行文件,但目标:元组中没有可执行文件。也许您想使用 --lib 来安装库。
【解决方案2】:

您还可以使用 lens包:

> import Control.Lens
> Prelude Control.Lens> view _1 (1,2)  -- Or (1,2) ^. _1
1
> Prelude Control.Lens> view _1 (1,2,3) -- Or (1,2,3) ^. _1
1
> Prelude Control.Lens> view _1 (1,2,3,4) -- Or (1,2,3,4) ^. _1
1
> Prelude Control.Lens> view _1 (1,2,3,4,5) -- Or (1,2,3,4,5) ^. _1
1

这不仅仅适用于第一个元素

> import Control.Lens
> Prelude Control.Lens> view _2 (1,2)  -- Or (1,2) ^. _2
2
> Prelude Control.Lens> view _3 (1,2,3) -- Or (1,2,3) ^. _3
3
> Prelude Control.Lens> view _4 (1,2,3,4) -- Or (1,2,3,4) ^. _4
4
> Prelude Control.Lens> view _5 (1,2,3,4,5) -- Or (1,2,3,4,5) ^. _5
5

我还写了一个类似问题的答案,该问题不仅仅涵盖元组: https://stackoverflow.com/a/23860744/128583

【讨论】:

    【解决方案3】:

    您可以为此键入自己的函数(我们将使用模式匹配):

    fst3 :: (a, b, c) -> a
    fst3 (x, _, _) = x
    

    你可以像这样使用它:

    fst3 ("string", 1, 1)
    

    【讨论】:

    • 谢谢,这正是我想要的。
    • @user2214957 如果您不知道(我看您是新用户):当您决定最喜欢哪个答案时,您应该接受它作为最佳/正确答案。
    【解决方案4】:

    我只想定义一个函数

    fst3 :: (a,b,c) -> a
    fst3 (x,_,_) = x
    

    这很容易理解并且没有奇怪的类型(sel1 的类型是Sel1 a b =&gt; a -&gt; b,这可能会令人困惑)

    或者您可以通过模式匹配提取您感兴趣的值,如[x | (x,_,_) &lt;- myThreeTupleList

    最后,最好的解决方案是使用更结构化的数据类型!当然,字符串和两个 int 具有更多含义,以某种方式对其进行编码是个好主意...

    【讨论】:

    【解决方案5】:

    你可以这样做:

    Prelude> let [(a,_,_)]=[("string",1,1)]
    Prelude> a
    "string"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-19
      • 1970-01-01
      • 2018-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多