gpt4 book ai didi

f# - 如何在模拟类似 Haskell 解决方案的 F# 中编写可变参数函数?

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

我如何(如果有的话)模仿 可变参数函数 (不是方法)这样我就可以写

sum 1 2 3
sum 1 2 3 4 5
sum 1 2 3 4 5 6 7
// etc.

上面的代码只是表示 示例 - 显然,如果我必须总结一个 list ,那么
[ 1; 2 ; 3] |> List.sum 

是一个更好的方法。

但是我正在寻找一个 结构相似 解决方案如 this Haskell solution

同样重要的是函数调用和参数值的正常语法保持不变。所以
sum 1 2 3

对比
sum(1, 2, 3)

这实际上意味着
let sum ([<ParamArray>] arr) = ...

在这种特定情况下不需要。

所有这一切的动机:我正在探索 F# 类型系统和语法的外围。而且我完全意识到我可能已经跨越了可能已经存在的边界。

PS:我的具体想法(我没有在这里描述)也可以完全不同地解决 - 所以我知道,所以我已经做了。
因此,我的问题不是:如何以不同的方式解决这个问题,而是如何像 Haskell 一样在结构上解决这个问题。

PPS:如果您可以使整个解决方案递归,则加倍 Karma-Points。

最佳答案

你说的是功能,不是方法。所以ParamArray不是一个选择。

您链接的 Haskell 代码基于推断的结果类型。

下面是一种根据 F# 中推断的结果类型进行解析的方法:

type T = T with
static member inline ($) (T, r:'t->'t ) = fun a b -> a + b
static member inline ($) (T, r:'t->'t->'t ) = fun a b c -> a + b + c
static member inline ($) (T, r:'t->'t->'t->'t) = fun a b c d -> a + b + c + d

let inline sum (x:'a) :'r = (T $ Unchecked.defaultof<'r>) x

let x:int = sum 2 3
let y:int = sum 2 3 4
let z:int = sum 2 3 4 5
let d:decimal = sum 2M 3M 4M

let mult3Numbers a b c = a * b * c
let res2 = mult3Numbers 3 (sum 3 4 ) 10
let res3 = mult3Numbers 3 (sum 3 4 5) 10

更新

从 F# 4.1 开始,上面的代码不再起作用(请参阅注释),但这里有一个更好的示例,其中递归多变量函数采用 n(无限)参数:
type T = T with
static member ($) (T, _:int ) = (+)
static member ($) (T, _:decimal) = (+)

let inline sum (i:'a) (x:'a) :'r = (T $ Unchecked.defaultof<'r>) i x

type T with
static member inline ($) (T, _:'t-> 'rest) = fun (a:'t) -> (+) a >> sum


let x:int = sum 2 3
let y:int = sum 2 3 4
let z:int = sum 2 3 4 5
let d:decimal = sum 2M 3M 4M

let mult3Numbers a b c = a * b * c
let res2 = mult3Numbers 3 (sum 3 4) (sum 2 2 3 3)
let res3 = mult3Numbers 3 (sum 3 4 5 11 13 20) 10

你也可以看看这个 polyvariadic fold .

关于f# - 如何在模拟类似 Haskell 解决方案的 F# 中编写可变参数函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28243963/

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