RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 602717
Accepted
Дмитрий Ярушин
Дмитрий Ярушин
Asked:2020-12-13 00:13:26 +0000 UTC2020-12-13 00:13:26 +0000 UTC 2020-12-13 00:13:26 +0000 UTC

请解释一下表达方式。F#

  • 772

请解释一下表达方式。F#

let rec fact n = iff ((=) n 1) 1 ((*) n (fact ((-) n 1)));; 
f#
  • 2 2 个回答
  • 10 Views

2 个回答

  • Voted
  1. Best Answer
    Fyodor Soikin
    2020-12-13T01:19:38Z2020-12-13T01:19:38Z

    关键字let指定某物的名称。大多数情况下,它为值定义一个名称:

    let x = 5      // числу 5 даём имя "x"
    let y = "abc"  // строке "abc" даём имя "y"
    

    它let大致翻译成俄语为“让”(在数学意义上):

    пусть х = 5
    пусть y = "abc"
    

    另一种情况是名称的定义不是针对值,而是针对函数。在这种情况下,紧跟在单词之后let,指示函数的名称,然后是参数,以空格分隔:

    let f x = x + 5
    

    这一行定义了一个函数f,它有一个参数x,函数的值是通过将参数的值加五来计算的。

    这个定义中的关键字rec表示该函数是递归的——也就是说,在计算它的值时,它自己使用。例如:

    let rec f x = if x = 1 then 1 else x*(f (x-1))
    

    1当参数为 时,此函数有一个值x=1,否则它的值是通过调用此函数本身并少一个参数来计算的。

    你的函数体使用了另一个函数iff。这个函数不在 F# 标准库中,所以我只能假设它是在代码中更高层的某个地方定义的。

    这个函数有三个参数:

    • (=) n 1
    • 1
    • (*) n (fact ((-) n 1))

    第二个参数只是常量“1”,没什么特别的。但是第一个和第三个参数是表达式,其中以前缀表示法调用运算符函数(而不是像通常的运算符那样以中缀表示)。在 F# 中,这是合法的并且经常使用。例如,(=) n 1- 与n = 1. 这里的运算符=用于前缀表示法,必须用括号括起来。相似地:

    • (-) n 1- 与n - 1
    • (*) x y- 与x * y

    因此,复数符号(*) n (fact ((-) n 1))与n * fact (n-1).

    所以你的整个函数可以这样重写:

    let rec fact n = iff (n=1) 1 (n * fact (n-1))
    

    请注意,此 c 表示法iff 不等同于 的类似表示法if .. then。它与计算函数参数的顺序有关。F# 使用参数求值的应用顺序——即所有参数的值在调用函数之前求值。在这种情况下,这意味着两个值n=1和都将在调用函数之前n * fact(n-1)进行评估,这意味着调用将在任何情况下执行,无论表达式是否为真。这将导致无限递归,最终导致堆栈溢出。ifffact(n-1)n=1

    从表达式的形式来看,我假设它的作者打算模仿 Lisp - 因此是运算符的前缀符号。这就是 Lisp 中的函数的样子:

    (defun f (n)
       (if (= n 1)
           1
           (* (f (- n 1)))))
    

    但是有一个重要的区别:ifLisp 中的表单,就像if .. thenF# 中的构造一样,不是普通的函数,而是所谓的“特殊形式”。当处理特殊形式时,编译器以一种特殊的方式表现 - 特别是,当处理 form 时,if编译器不会评估所有三个参数,而是首先评估第一个,然后是第二个或第三个(但不是同时在同时)。这在您的示例中不会发生,因为它iff只是一个常规函数,这将导致堆栈溢出。

    • 4
  2. Дмитрий Ярушин
    2020-12-13T00:54:14Z2020-12-13T00:54:14Z

    从人的角度来看,它看起来像这样:

       let rec fact n =
          if n=1 then 1
          else n*fact(n-1)
    

    如果我们加上fact 5,那么它会计算 5 的阶乘。

    来找我)

    • 0

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    如何停止编写糟糕的代码?

    • 3 个回答
  • Marko Smith

    onCreateView 方法重构

    • 1 个回答
  • Marko Smith

    通用还是非通用

    • 2 个回答
  • Marko Smith

    如何访问 jQuery 中的列

    • 1 个回答
  • Marko Smith

    *.tga 文件的组重命名(3620 个)

    • 1 个回答
  • Marko Smith

    内存分配列表C#

    • 1 个回答
  • Marko Smith

    常规赛适度贪婪

    • 1 个回答
  • Marko Smith

    如何制作自己的自动完成/自动更正?

    • 1 个回答
  • Marko Smith

    选择斐波那契数列

    • 2 个回答
  • Marko Smith

    所有 API 版本中的通用权限代码

    • 2 个回答
  • Martin Hope
    jfs *(星号)和 ** 双星号在 Python 中是什么意思? 2020-11-23 05:07:40 +0000 UTC
  • Martin Hope
    hwak 哪个孩子调用了父母的静态方法?还是不可能完成的任务? 2020-11-18 16:30:55 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    user207618 Codegolf——组合选择算法的实现 2020-10-23 18:46:29 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    Arch ArrayList 与 LinkedList 的区别? 2020-09-20 02:42:49 +0000 UTC
  • Martin Hope
    iluxa1810 哪个更正确使用:if () 或 try-catch? 2020-08-23 18:56:13 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5