f# - 在 F# 中通过组合定义 EntryPoint

标签 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)使用组合时。

我可能缺少类型系统,所以我的问题是为什么不能在这里通过组合定义 main ?

最佳答案

简短的回答是在 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 .

关于f# - 在 F# 中通过组合定义 EntryPoint,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41604526/

相关文章:

ocaml - Jane Street 的 ‘Base’ 、 ‘Core’ 和 'Core_kernel' 有什么区别?

ocaml - 如何在没有库函数的ocaml中实现整数与大整数的乘法?

wpf - 使用 WPF 和 MVVM 编辑 F# 记录

ocaml - `brew install infer` 更新推断时出错

integer - 为什么 OCaml 中的 int 只有 31 位?

f# - 在 F# 中将 int [,] 转换为 int [] [] 的简单方法

exception - 使用mem然后find还是使用find并处理异常?

f# 重复定义

f# - 如何在 F# 中执行链式回调?

azure - F# Azure 辅助角色和目标运行时