首页>Program>source

在F#中:

> let f x = x + 2;;
val f : int -> int
> let g x = f x;;
val g : int -> int
> g 10;;
val it : int = 12
> let f x = x + 3;;
val f : int -> int
> g 10;;
val it : int = 12

在Clojure中:

1:1 user=> (defn f [x] (+ x 2))
#'user/f
1:2 user=> (defn g [x] (f x))
#'user/g
1:3 user=> (g 10)
12
1:4 user=> (defn f [x] (+ x 3))
#'user/f
1:5 user=> (g 10)
13

请注意,在Clojure中,最后一行调用了f的最新版本.在F#中,仍然会调用f的旧版本.为什么会这样?它如何工作?

最新回答
  • 1月前
    1 #

    正如gabe所说,当您输入具有以下名称的函数时,F#交互会使用shadowing值 已经存在(有关阴影的更多信息,请参见此SO问题).这意味着当您运行代码时,F#编译器会看到以下内容:

    > let [email protected] x = x + 2;; 
    > let [email protected] x = [email protected] x;; 
    > [email protected] 10;; 
    val it : int = 12
    > let [email protected] x = x + 3;; 
    > [email protected] 10;; 
    val it : int = 12
    

    F#使用一些错误的名称(例如@),您不能直接使用它们来区分值的版本.另一方面,Clojure的行为可能最好理解为功能的大词典.使用伪语法,如下所示:

    > symbols[f] = fun x -> x + 2;; 
    > symbols[g] = fun x -> symbols[f] x;; 
    > symbols[g] 10;; 
    val it : int = 12
    > symbols[f] = fun x -> x + 3;; 
    > symbols[g] 10;; 
    val it : int = 13
    

    这应该使区别很清楚。

    附带说明,Clojure方法存在一个可能的问题(至少对于F#之类的语言而言).您可以声明某种类型的函数,然后使用它,下一条命令可以更改函数的类型.如果F#使用Clojure方法,以下示例应如何工作?

    > let f a b = a + b;;
    > let g x = f x x;;
    > let f () = printf "f!";;
    > g 0;;
    

    函数 g   使用 f   好像它有两个 int类型的参数 ,但粗线更改了函数的类型.对于类型检查语言,这使Clojure方法有点棘手。

  • 1月前
    2 #

    在Clojure中, f   符号捕获名称 f ,而在F#中,   符号捕获 f的值 .因此,每次您致电 f时,在Clojure   它看起来 g   找出当时名称的含义,而在F#中,每次调用 f   使用 g的值   有当 f   函数最初是创建的。

  • 1月前
    3 #

    Gabe和Tomas很好地涵盖了基础知识.请注意,如果您希望F#像Clojure那样运行,则可以使用可变绑定并重新分配 g

    f
    
    let mutable f = fun x -> x + 2 let g x = f x g 10;; // 12 f <- fun x -> x + 3 // note, assign new value, don't create new binding g 10;; //13

  • java:如何在休眠状态下延迟加载多对多集合?
  • ios:NSNotificationCenter是否删除Observer:从接收Memorywarning通知中注销VC?