我找到了唐·西姆的一个介绍性,这表明艾朗的
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#重写它?
发布于 2016-03-23 01:23:46
您可以通过稍微重新思考问题来实现接近过载的目标。不要把函数看作是可变性的轴,而是把输入看作可变的部分。如果你这样做,你会意识到你可以在受歧视的工会中实现同样的目标。
这里有一个比链接文章中的例子更巧妙的例子:
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
那样定义这样一个“愚蠢”类型,而是定义一个在您正在建模的领域中有意义的受歧视的联盟。
https://stackoverflow.com/questions/36173739
复制