通过F#中的组合定义EntryPoint

时间:2017-01-12 03:16:28

标签: f# ocaml

我试图更好地理解功能编码方式,并且只写了一个小程序来打印用户输入数字的阶乘:

open System

let fact n = let rec factiter init acc = 
                      if init = 0 then acc
                      else factiter (init - 1) init*acc
             factiter n 1


let dropStrArr (argv: string []) = ignore argv

let factComp = Console.ReadLine >> Int32.Parse >> fact >> Console.WriteLine >> fun () -> 0

[<EntryPoint>]
let main argv = (dropStrArr >> factComp) argv

这个工作正常但后来我认为main可以纯粹由作文定义并尝试:

let main = dropStrArr >> factComp

我认为它会起作用,但是虽然它会编译,但它会在运行时立即退出。

这两种情况有不同的类型:     unit -> int 当main用其参数定义时,相对于     (unit -> int) 使用作文时。

我可能对类型系统缺失了,所以我的问题是为什么不能通过合成来定义主要的?

1 个答案:

答案 0 :(得分:5)

简短的回答是,在F#中编写无点样式会产生后果。

部分应用的函数,汇编到FSharpFunc并随后使用Invoke调用。

举例说明:

let mul a b = a + b
let mul2 = mul 2 //point-free
let mul2P a = mul 2 a //pointed

mul2P看起来像你期望的那样(在等效的C#中)

static int mul2P(int a) { return mul(2, a); }

mul2变为

class mul2Impl : FSharpFunc<int, int>
{       
    public int a;
    mul2Impl(int a) { this.a = a; }

    public override int Invoke(int b)
    {
        return mul(this.a, b);
    }
}

所以当你写let main argv时,它就变成了一个简单的静态方法,只用

调用另外两个FSharpFunc
factComp.Invoke(dropStrArr.Invoke(argv));

但是当你撰写它时,main会变成FSharpFunc而且不再有a static main method as is required