【问题标题】:How to pattern match a variable length tuple如何模式匹配可变长度的元组
【发布时间】:2019-12-06 22:22:47
【问题描述】:

我有一些像这样的实用函数,它们返回不同长度的元组:

let get1And2Of4(v1, v2, v3, v4) = v1, v2
let get1And2And3Of4(v1, v2, v3, v4) = v1, v2, v3

我希望能够对变量进行模式匹配并返回适当的实用函数。

例如,

let bar = 
     match foo with
     | "A" -> get1And2Of4
     | "B" -> get1And2And3Of4

但是,编译器会抱怨,因为元组的长度不同。阅读Variable length tuples in f# 和Elegant pattern matching on nested tuples of arbitrary length 说明这是不可能的。

鉴于我需要使用元组而不是列表,是否还有其他选择可以实现这一点?

【问题讨论】:

  • myFrame |> Series.mapValues (Stats.levelMean myLvlFun) 中请注明myFrame、Series.mapValues、Stats.levelMean的类型。这将明确myLvlFun 的所需类型。
  • 这些来自 Deedle 库 bluemountaincapital.github.io/Deedle,但我会更新问题以包括在内。
  • 从类型签名中,你有一个Series<(int * string * string * int),float>,并且想用mapValues改变第二个参数,所以你需要给它一个函数float -> b才能得到一个@987654334 @ 到底。它是否正确?您还没有接近给它float -> b,所以我可能是错的。我们几乎没有什么信息可以猜测您要做什么,因为您给出了一个不起作用的方法,但是问题的定义是由一行代码给出的,这也没有意义。很难猜出你的问题是什么。
  • 不幸的是,这并没有成为一个更容易理解的问题。 “保持这个的最佳选择是什么”是一个问题,但寻求替代的东西不存在,所以这应该是“什么是最好的方法来做到这一点”,但你还没有说什么“这个”是。
  • 您希望bar 返回两部分或三部分的元组。让我们想象一下已经完成了。你能指定接下来你想用这个值做什么吗?如果您对列表样式的操作不感兴趣,但对元组样式的操作感兴趣,您希望对其执行哪些操作?你将无法做到,例如。 bar.Third 如果bar 不一定包含Third 组件。

标签: f#


【解决方案1】:

我能想象的唯一可行的、类型安全的方法是明确地拼写出来,并将函数作为单个案例包装在一个有区别的联合中。这显然很尴尬;从好的方面来说,它可以帮助您跟踪所涉及的各种类型参数,因为最终所有代码路径都需要返回相同的类型。

type WhateverYouFeelNamingTheDU<'a,'b,'c,'d> =
| Get1And2Of4 of ('a * 'b * 'c * 'd -> 'a * 'b)
| Get1And2And3Of4 of ('a * 'b * 'c * 'd -> 'a * 'b * 'c)
let get1And2Of4 = Get1And2Of4(fun (v1, v2, _, _) -> v1, v2)
let get1And2And3Of4 = Get1And2And3Of4(fun (v1, v2, v3, _) -> v1, v2, v3)

match "foo" with
| "A" -> get1And2Of4
| _ -> get1And2And3Of4
|> function
| Get1And2Of4 f42 -> f42 (1,2,"a","b") |> string
| Get1And2And3Of4 f43 -> f43 (3,4,"c","d") |> string
// val it : string = "(3, 4, c)"

【讨论】:

  • 我对 F# 还是比较陌生。如果可能的话,你能解释一下比赛结束后发生了什么吗?看起来您正在将返回类型与新函数匹配,然后执行该函数。对吗?
  • 因为我试图将生成的可变长度元组传递给另一个函数(该函数不关心元组长度,它只需要一个元组)强制返回类型为字符串不起作用。它必须是一个元组。
  • @StringerBell 如果你不玩任何反射技巧,你就不能拥有一个不关心元组长度的函数,因为对于采用元组的 f# 函数,长度是固定的,并且其签名的固有部分。您可能正在考虑params[],这是一种具有可变数量参数的方法,但它实际上是一个数组。现在,f# 中的可区分联合用作求和类型,您可以使用它们将 2 元组与 3 元组分开,并在各自的匹配子句中相应地传递它们。
  • 我正在使用 Deedle,它有这个function,据我所知,它可以让我传入一个可变长度的元组......在一天结束时我试图通过在我的任何实用程序函数中作为 levelSel 参数。
猜你喜欢
  • 1970-01-01
  • 2016-09-04
  • 2017-07-15
  • 2023-03-27
  • 1970-01-01
  • 2011-11-16
  • 2019-05-01
  • 2013-08-19
  • 1970-01-01
相关资源
最近更新 更多