gpt4 book ai didi

f# - FSharp 检查元组类型是否

转载 作者:行者123 更新时间:2023-12-02 02:58:37 27 4
gpt4 key购买 nike

我想以特定方式格式化元组,并且我尝试通过检查元组的类型(2 个元素、3 个元素等)来实现此目的。我在第三行收到错误消息:

This runtime coercion of type test from type
'd
to
'a * ('b * 'c)
involves an indeterminate type based on the information prior to this program point.
Runtime type tests are not allowed on some type. Further type annotations are needed.

这是我的尝试:

  let namer x =
match x with
| :? ('a * ('b * 'c)) as a, b, c -> sprintf "%s_%s_%s" (a.ToString()) (b.ToString()) (c.ToString())
| :? ('a * 'b) as a, b -> sprintf "%s_%s" (a.ToString()) (b.ToString())
| a -> sprintf "%s" (a.ToString())

你应该如何做这样的事情?我希望能够根据元组的类型格式化字符串。

我最终想要的是能够将嵌套元组“展平”为没有一堆括号的字符串。例如:

// What I want
let x = (1, (2, (3, 4)))
let name = namer x
printfn "%s" name
> 1_2_3_4

更新:这与问题“如何在 F# 列表和 F# 元组之间进行转换?”不同。找到here 。我知道该怎么做。我想要的是能够检测我是否有元组以及元组的类型。理想的情况是一个通用函数,可以采用单个元素、元组或嵌套的 2 元素元组。例如,法律论点是:

let name = namer 1
// or
let name = namer (1, 2)
// or
let name = namer (1, (2, 3))
// or
let name = namer (1, (2, (3, 4)))

我还想处理非整数值。例如:

let name = namer (1, ("2", (3, "chicken")))

最佳答案

您可以通过一些反射和共同递归函数来实现这一点:

let isTuple tuple =
tuple.GetType() |> Reflection.FSharpType.IsTuple

let getFields (tuple: obj) =
tuple |> Reflection.FSharpValue.GetTupleFields |> Array.toList

let rec flatten fields =
List.collect namer fields

and namer (tuple: obj) =
if isTuple tuple
then tuple |> getFields |> flatten
else [tuple]

namer(1, "test") |> printfn "%A"
namer(1, ("2", (3, "chicken"))) |> printfn "%A"

Try it online!

灵感来源:

关于f# - FSharp 检查元组类型是否,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60510868/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com