gpt4 book ai didi

f# - 在 F# 中重写 Erlang

转载 作者:行者123 更新时间:2023-12-04 14:41:50 25 4
gpt4 key购买 nike

我找到了 presentation由 Don Syme 所著,这表明 Erlang 的

fac(0) -> 1
fac(N) -> N * fac(N-1).

相当于 F# 的
let rec fac = function
| 0 -> 1
| n -> n * fac (n-1)

但看起来没有办法在不失去类型安全的情况下将模式匹配用于不同的数量。例如。可以使用列表模式匹配,但类型必须是通用基本类型(例如 object ):
let concat = function
| [x;y] -> x.ToString() + y.ToString()
| [x] -> x.ToString()

鉴于模块中的 F# 函数不支持重载,看来使用静态类型将 Erlang 代码重写为 F# 的唯一方法是使用具有方法重载的静态类而不是模块。有没有更好的方法在 F# 中重写具有不同数量的 Erlang 函数?

一般来说,说 Erlang 的参数匹配更接近 .NET(包括 C#)的方法重载而不是 F# 的模式匹配是否正确?或者两者之间没有直接替代,例如Erlang 中可能有一个函数,具有不同的元数 + 一个守卫:
max(x) -> x.
max(x,y) when x > y -> x.
max(x,y) -> y.
max(comparer, x, y) -> if comparer(x,y) > 0 -> x; true -> y end.

在最后一种情况下,参数是不同类型的。你会如何用 F# 重写它?

最佳答案

通过稍微重新考虑问题,您可以实现接近重载的目标。与其将函数视为可变性轴,不如将输入视为可变部分。如果你这样做,你会意识到你可以achieve the same with a discriminated union .

这是一个比链接文章中的示例更人为的示例:

type MyArguments = One of int | Two of int * int

let foo = function
| One x -> string x
| Two (x, y) -> sprintf "%i%i" x y

用法:
> foo (One 42);;
val it : string = "42"
> foo (Two (13, 37));;
val it : string = "1337"

显然,不是像上面 MyArguments 那样定义这样的“愚蠢”类型。 ,您将定义一个在您正在建模的域中有意义的有区别的联合。

关于f# - 在 F# 中重写 Erlang,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36173739/

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