【问题标题】:F#: How to process a list of tuples?F#:如何处理元组列表?
【发布时间】:2018-10-22 23:59:27
【问题描述】:

我正在做家庭作业。而且我正在尝试学习 F#,所以除了使用 List.Map 或 lambdas 之类的基本东西之外,我不想要任何快捷方式。 我正在尝试处理元组列表,但在访问列表中的元组时遇到问题。 我想获取元组列表,将每个元组中的数字相加,然后返回该数字,每次都打印出来。

let listTup = [(2,3,4); (4,5,6); (6,7,8)]

let getSum (a,b,c) =
    a+b+c

let rec printSum tpList =
let total = 0
match tpList with
| [] -> total //return 0 if empty list
| hd::tl -> 
    print (getSum hd)

【问题讨论】:

  • 我已经忘记了语法,match ... (x, y, z)::tl -> print (getSum x y z); printSum tl 可以工作吗?
  • 一个建议:确保匹配表达式的所有分支都评估为相同的类型。

标签: f# f#-interactive


【解决方案1】:

您要做的第一件事是通过getSum 函数映射您的元组。这可以通过将元组列表传递到List.map getSum 来非常简单地完成。然后您想打印列表中的每个元素,因此您使用函数printfn "%d" 将List.map getSum 的结果通过管道传输到List.iter。这是因为函数具有咖喱参数。 printfn "%d" 将"%d" 参数应用于printfn 并返回一个采用整数的函数,然后将其打印出来。整个事情看起来像这样:

let listTup = [(2,3,4); (4,5,6); (6,7,8)]

let getSum (a,b,c) =
    a + b + c

let printSum tpList =
    tpList |> List.map getSum |> List.iter (printfn "%d")

打印出来:

9
15
21

如果我们利用函数组合(>> 运算符),我们甚至可以进一步简化函数。请注意,printSum 将tpList 作为其参数,然后仅将其用作流水线连接在一起的两个函数的输入。由于流水线只是获取一个函数的输出并将其作为另一个函数的最后一个参数传递,所以我们真正需要做的就是编写函数List.map getSum,它接受一个int 三元组列表并返回一个ints 和 List.iter (printfn "%d"),它采用 ints 的列表并返回单位。看起来像这样:

let printSum = List.map getSum >> List.iter (printfn "%d")

这将打印相同的结果,但表达函数的方式更简单。

【讨论】:

    【解决方案2】:

    F# 也有命令式循环。在这种情况下,我认为命令式循环最符合问题。

    let listTup = [(2,3,4); (4,5,6); (6,7,8)]
    for a,b,c in listTup do
      let sum = a + b + c
      printfn "%d" sum
    

    【讨论】:

    • “命令式循环最符合问题的习惯” - 用函数式语言?
    • @Enigmativity 当然不是:函数式语言没有命令式循环。 F# 可以,而且我认为它们最能解决手头的问题。
    • 我几乎总是更喜欢尾递归或列表处理而不是 F# 中的循环。以后增强、重构或并行化更容易,而且在列表处理的情况下,我认为它把重点放在逻辑而不是机制上。..
    • @Aaron for 循环风格是我很久以前从 Tomas Petricek 那里采用的一种。在 F# 中全职工作了四年,现在我仍然喜欢它。我认为应该编写命令式代码,使其显而易见。 List.Iter 总是觉得你在向我扫除地毯下的副作用。 For 循环使它很明显。 stackoverflow.com/a/33847782/171121
    • 如果我们只是打印一个列表,我可能会考虑一个循环。但是,因为我们是在求和然后打印列表,所以我仍然更喜欢列表处理语法。例如,考虑我们将这段代码放入我们的测试环境并发现列表中的getSum 过于昂贵的情况,我们需要对其进行优化。在列表处理版本中,我们可以简单地将printSum 更改为let printSum = List.toArray >> Array.Parallel.map getSum >> Array.iter (printfn "%d")。在循环版本中,它是一个重写。
    猜你喜欢
    • 2018-08-05
    • 2015-05-18
    • 1970-01-01
    • 2010-11-30
    • 2020-05-02
    • 1970-01-01
    • 1970-01-01
    • 2016-05-25
    • 1970-01-01
    相关资源
    最近更新 更多