gpt4 book ai didi

f# - 我可以在柯里化(Currying)函数上应用运算符,使其返回类型为 unit 而不指定参数数量吗?

转载 作者:行者123 更新时间:2023-12-04 06:52:36 26 4
gpt4 key购买 nike

给定一个具有任意参数类型和数量的任意函数 func,我想得到一个返回单位的函数 -- func,返回值被忽略。将其视为对纯副作用函数的投影。如果 func 接受一个参数(或者如果它是非柯里化(Currying)形式),它只是 func>>ignore。显而易见的解决方案是为我们需要的 func 的每个参数编写一个通用运算符:

let inline unitise1 f a = f a |> ignore
let inline unitise2 f a b = f a b |> ignore
let inline unitise3 f a b c = f a b c |> ignore
let inline unitise4 f a b c d = f a b c d |> ignore

等这很麻烦而且很不方便,因为我们每次都需要计算参数,并且代码不会很好地重构。是否有一种我缺少的语言结构可以让这个更干净?

编辑:我相信这样的运算符会很有用,因为 NET 泛型比 F# 静态解析类型参数弱。这就是我的意思。假设我有一个高阶函数

let inline higher f g =
f 7 |> ignore
g 3 |> ignore

只要第一个参数是 int,我们就可以向它传递任何函数。所以这会起作用:

let add n = n+1
let str (n:int) = n.ToString()
higher add str
higher str add

特别是,不需要通用类型注释。这就是我们对 F# 的了解和喜爱。现在,我遇到的情况是我需要传递大量(~15)个函数作为 higher 的参数。它们将多次沿调用链向下传递。将它们分组到一个数据结构中是很自然的。

type Funcs<'R1,'R2,'R3> = {f1:int->'R1;f2:int->'R2;f3:int->'R3}

在达到 15 个通用参数之前,这会变得很难看。仅当涉及功能时,才可能进行类型注释。如果我可以将函数统一化,我会将 higher 更改为

let inline higher f g =
f 7
g 3

并且会使用辅助函数,在从它们构建 Funcs 之前将每个函数统一起来。在这个玩具示例中,fg 都有一个参数,因此解决方案很简单,但在实际情况中,不同的函数具有不同数量的参数。

自从写完这个问题后,我咬紧牙关写了一个包含 15 个通用参数的 Funcs 的庞然大物。

最佳答案

@TomasPetricek 是绝对正确的,你不能建立这样的功能。 这是证据。

假设,您创建了unitise功能,以便以下工作:

// just sample functions with 1, 2, and 3 curried arguments
let f1 a = a
let f2 a b = (a,b)
let f3 a b c = (a,b,c)

let x1 = unitise f1 5 // expected x1:unit
let x2 = unitise f2 5 42 // expected x2:unit
let x3 = unitise f3 5 "foobar" 42 // expected x3:unit

任意数量的 curried 参数没有泛型,所以你必须计算 (f1 5) , (f2 5 42)等调用 unitise 之前:

let x1 = unitise (f1 5)             // expected x1:unit
let x2 = unitise (f2 5 42) // expected x2:unit
let x3 = unitise (f3 5 "foobar" 42) // expected x3:unit

因此,unitise变得等同于 ignore :

let x3 = ignore (f3 5 "foobar" 42) // expected x3:unit

如果你愿意ignore (或 unitise )放置在语句的最开头并为了可读性避免括号,考虑使用高优先级,右关联向后管道(^<|) :

let inline (^<|) f a = f a

那么您的代码将如下所示:

let x1 = ignore ^<| f1 5             // expected x1:unit
let x2 = ignore ^<| f2 5 42 // expected x2:unit
let x3 = ignore ^<| f3 5 "foobar" 42 // expected x3:unit

关于f# - 我可以在柯里化(Currying)函数上应用运算符,使其返回类型为 unit 而不指定参数数量吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24366392/

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