问题描述
我几乎不了解F#。我甚至不知道语法,所以我不能给出例子。
在一个注释线程中提到F#可以声明函数,可以采取多个参数可能的类型,例如字符串或整数。这将类似于C#中的方法重载:
public void方法(string str){/ * ... * /}
public void Method(int integer){/ * ... * /}
,在CIL中,您不能声明此表单的委托。每个代理必须具有单个特定的参数类型列表。因为F#中的函数是一流的公民,然而,它似乎应该能够传递这样的函数,唯一的方法编译成CIL是使用委托。
那么,F#如何编译为CIL?
函数可以接受多个不同的参数集,只需创建方法重载:
string f(int x)
{
returnint+ x;
}
string f(string x)
{
returnstring+ x;
}
void callF()
{
Console.WriteLine(f(12));
Console.WriteLine(f(12));
}
//没有办法写这样的函数:
void call(Func< int | string,string> func)
{
Console.WriteLine (func(12));
Console.WriteLine(func(12));
}
callF
函数是非常简单,但是我的调用
函数的语法不起作用。
写F#,你需要一个可以接受多个不同参数集的函数,你创建一个歧视的联合,可以包含所有不同的参数集,你做一个单一的函数,需要该联合:
type Either = Int int
|的Int字符串
let f = function Int x - > int+ string x
| String x - > string+ x
let callF =
printfn%s(f(Int 12))
printfn%s
让调用func =
printfn%s(func(Int 12))
printfn%s(func(String12))
作为单个函数, f
可以像任何其他值,所以在F#中我们可以写 callF
和调用f
,两者做同样的事情。
那么F#如何实现上面创建的 Either
类型呢?基本上这样:
public abstract class
{
public class Int:Test.Either
{
internal readonly int item;
internal Int(int item);
public int Item {get; }
}
public class String:Test.Either
{
internal readonly string item;
internal String(string item);
public string Item {get; }
}
}
调用
函数是:
public static void call(FSharpFunc< Either,string> f);
并且 f
看起来像这样: / p>
public static string f(_arg1)
{
if(_arg1是Either.Int)
returnint+((Either.Int)_arg1).Item;
returnstring+((Either.String)_arg1).Item;
}
当然你可以实现相同的 code>键入C#(duh!),但它不是惯用的,这就是为什么它不是上一个问题的明显答案。
I know virtually nothing about F#. I don’t even know the syntax, so I can’t give examples.
It was mentioned in a comment thread that F# can declare functions that can take parameters of multiple possible types, for example a string or an integer. This would be similar to method overloads in C#:
public void Method(string str) { /* ... */ }
public void Method(int integer) { /* ... */ }
However, in CIL you cannot declare a delegate of this form. Each delegate must have a single, specific list of parameter types. Since functions in F# are first-class citizens, however, it would seem that you should be able to pass such a function around, and the only way to compile that into CIL is to use delegates.
So how does F# compile this into CIL?
When you're writing C# and you need a function that can take multiple different parameter sets, you just create method overloads:
string f(int x)
{
return "int " + x;
}
string f(string x)
{
return "string " + x;
}
void callF()
{
Console.WriteLine(f(12));
Console.WriteLine(f("12"));
}
// there's no way to write a function like this:
void call(Func<int|string, string> func)
{
Console.WriteLine(func(12));
Console.WriteLine(func("12"));
}
The callF
function is trivial, but my made-up syntax for the call
function doesn't work.
When you're writing F# and you need a function that can take multiple different parameter sets, you create a discriminated union that can contain all the different parameter sets and you make a single function that takes that union:
type Either = Int of int
| String of string
let f = function Int x -> "int " + string x
| String x -> "string " + x
let callF =
printfn "%s" (f (Int 12))
printfn "%s" (f (String "12"))
let call func =
printfn "%s" (func (Int 12))
printfn "%s" (func (String "12"))
Being a single function, f
can be used like any other value, so in F# we can write callF
and call f
, and both do the same thing.
So how does F# implement the Either
type I created above? Essentially like this:
public abstract class Either
{
public class Int : Test.Either
{
internal readonly int item;
internal Int(int item);
public int Item { get; }
}
public class String : Test.Either
{
internal readonly string item;
internal String(string item);
public string Item { get; }
}
}
The signature of the call
function is:
public static void call(FSharpFunc<Either, string> f);
And f
looks something like this:
public static string f(Either _arg1)
{
if (_arg1 is Either.Int)
return "int " + ((Either.Int)_arg1).Item;
return "string " + ((Either.String)_arg1).Item;
}
Of course you could implement the same Either
type in C# (duh!), but it's not idiomatic, which is why it wasn't the obvious answer to the previous question.
这篇关于F#如何编译可以将多个不同的参数类型转换为IL的函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!