F# 入门(斐波那契和函数表达式)
Introductory F# (Fibonacci and function expressions)
我已经开始学习 F# 入门课程,但我在完成两项作业时遇到了一些问题。第一个让我创建两个函数,其中第一个函数接受一个输入并将其与四个相加,第二个函数计算 sqrt(x^2+y^2)。然后我应该为它们都编写函数表达式,但由于某种原因它给了我错误 "Unexpected symbol'|' in implementation file".
let g = fun n -> n + 4;;
let h = fun (x,y) -> System.Math.Sqrt((x*x)+(y*y));;
let f = fun (x,n) -> float
|(n,0) -> g(n)
|(x,n) -> h(x,n);;
第二个作业要求我创建一个函数,用于查找斐波那契数列。我写了下面的代码,但它似乎忘记了开头的 0,因为输出总是 n+1 而不是 n。
let rec fib = function
|0 -> 0
|1 -> 1
|n -> fib(n-1) + fib(n-2)
;;
请记住,这是第一周,所以我应该能够使用这些方法创建它们。
您的第一个片段主要有两个问题:
在F#中,float
和int
是有区别的。您将整数值写为 4
或 0
,将浮点值写为 4.0
或 0.0
。 F#不会自动将整数转换为浮点数,所以需要保持一致。
您在 f
函数中的语法有点奇怪 - 我不确定 float
应该是什么意思以及 fun
和 function
构造行为不同。
因此,从您的原始代码开始:
let g = fun n -> n + 4;;
这行得通,但我不会使用 fun
将其写为显式函数 - 您也可以使用 let
来定义函数,而且它更简单。此外,在 F# Interactive 中您只需要 ;;
,但如果您使用任何带有命令的合适编辑器将代码发送到 F# interactive(通过 Alt+Enter),则不需要它。
但是,在您的 f
函数中,您想要 return float
因此您也需要将 g
修改为 return 浮动。这意味着将 4
替换为 4.0
:
let g n = n + 4.0
h
函数很好,但是你可以用let
重新写:
let h (x,y) = System.Math.Sqrt((x*x)+(y*y));;
在你的 f
函数中,你可以使用 function
来编写一个使用模式匹配的函数,或者你可以使用更详细的语法 match
(function
只是一个 shorthand 用于编写函数然后在输入上进行模式匹配):
let f = function
| (n,0.0) -> g(n)
| (x,n) -> h(x,n)
let f (x, y) =
match (x, y) with
| (n,0.0) -> g(n)
| (x,n) -> h(x,n)
另请注意缩进很重要 - |
之前需要空格。
我将处理您的第一段代码,斐波那契函数留待以后处理。先转一下你的代码,再说吧
let g = fun n -> n + 4;;
let h = fun (x,y) -> System.Math.Sqrt((x*x)+(y*y));;
let f = fun (x,n) -> float
|(n,0) -> g(n)
|(x,n) -> h(x,n);;
第一条评论:如果您正在定义一个函数并立即将其分配给一个名称,就像在所有这些示例中一样,您不需要 fun
关键字。通常定义函数的方式是写成let (name) (parameters) = (function body)
。所以你上面的代码将变成:
let g n = n + 4;;
let h (x,y) = System.Math.Sqrt((x*x)+(y*y));;
let f (x,n) = float
|(n,0) -> g(n)
|(x,n) -> h(x,n);;
我没有做任何其他更改,所以您的 f
函数仍然有错误。接下来让我们解决该错误。
我认为您在这里犯的错误是认为 fun
和 function
可以互换。他们不是。 fun
是标准函数定义,但 function
是另外一回事。在 F# 中编写如下函数是一种非常常见的模式:
let someFunc parameter =
match parameter with
| "case 1" -> printfn "Do something"
| "case 2" -> printfn "Do something else"
| _ -> printfn "Default behavior"
function
关键字是shorthand一个参数加一个匹配表达式。换句话说,这个:
let someFunc = function
| "case 1" -> printfn "Do something"
| "case 2" -> printfn "Do something else"
| _ -> printfn "Default behavior"
与此完全相同的代码:
let someFunc parameter =
match parameter with
| "case 1" -> printfn "Do something"
| "case 2" -> printfn "Do something else"
| _ -> printfn "Default behavior"
只有一处不同。在带有 function
关键字的版本中,您无法选择参数的名称。它由 F# 编译器自动创建,并且由于您无法提前知道参数的名称,因此您无法在代码中引用它。 (好吧,有很多方法,但我不想让你在学会走路之前就学会 运行,可以这么说)。还有一件事:当您仍在学习 F# 时,我强烈建议您不要使用 function
关键字。一旦您知道自己在做什么,它就非常有用,但在您的早期学习阶段,您应该使用更明确的 match (parameter) with
表达式。这样你就会习惯于看到它在做什么。一旦您使用 F# 几个月,就可以开始用更短的 let f = function (...)
替换那些 let f param = match param with (...)
表达式。但在 match param with (...)
真正深入理解之前,您应该继续明确地输入它。
所以您的 f
函数应该如下所示:
let f (x,n) =
match (x,n) with
|(n,0) -> g(n)
|(x,n) -> h(x,n);;
我看到当我输入这个时,Tomas Petricek 发布了一个回复,它解决了 float
的不正确用法,所以我不会重复他对你为什么会得到一个f
函数中的 float
字词错误。他还解释了 ;;
,所以我也不会重复。我只想说,当他提到 "any decent editor with command for sending code to F# interactive (via Alt+Enter)" 时,有很多编辑器选择——但作为初学者,您可能只想有人向您推荐一个,所以我会推荐一个。不过,首先:如果您使用 Windows,您可能已经在使用 Visual Studio,在这种情况下,您应该坚持使用 Visual Studio,因为您知道它。它是 F# 的一个很好的编辑器。但是,如果您还没有使用 Visual Studio,我不建议您下载它只是为了玩弄 F#。这是一个程序的野兽,专为专业软件开发人员设计,可以完成他们在工作中需要做的各种事情,因此如果您刚刚开始使用它,可能会感到有点不知所措。所以我实际上会推荐一些更轻量级的东西:编辑器调用 Visual Studio 代码。它是跨平台的,将 运行 在 Linux、OS X 或 Windows 上完美运行。下载并安装 VS Code 后,您将需要安装 Ionide 扩展。 Ionide 是 VS Code 的插件(也适用于 Atom,尽管 Ionide 的 Atom 版本更新频率较低,因为现在所有 Ionide 开发人员都使用 VS Code),这使得 F# 编辑成为一种真正的乐趣。实际上,您会发现三个扩展:Ionide-fsharp、Ionide-FAKE 和 Ionide-Paket。下载并安装这三个工具:FAKE 和 Paket 是两个您可能不需要的 F# 编程工具,但是一旦您需要它们,您就已经安装了它们。
好的,我想这足以让你开始了。
我已经开始学习 F# 入门课程,但我在完成两项作业时遇到了一些问题。第一个让我创建两个函数,其中第一个函数接受一个输入并将其与四个相加,第二个函数计算 sqrt(x^2+y^2)。然后我应该为它们都编写函数表达式,但由于某种原因它给了我错误 "Unexpected symbol'|' in implementation file".
let g = fun n -> n + 4;;
let h = fun (x,y) -> System.Math.Sqrt((x*x)+(y*y));;
let f = fun (x,n) -> float
|(n,0) -> g(n)
|(x,n) -> h(x,n);;
第二个作业要求我创建一个函数,用于查找斐波那契数列。我写了下面的代码,但它似乎忘记了开头的 0,因为输出总是 n+1 而不是 n。
let rec fib = function
|0 -> 0
|1 -> 1
|n -> fib(n-1) + fib(n-2)
;;
请记住,这是第一周,所以我应该能够使用这些方法创建它们。
您的第一个片段主要有两个问题:
在F#中,
float
和int
是有区别的。您将整数值写为4
或0
,将浮点值写为4.0
或0.0
。 F#不会自动将整数转换为浮点数,所以需要保持一致。您在
f
函数中的语法有点奇怪 - 我不确定float
应该是什么意思以及fun
和function
构造行为不同。
因此,从您的原始代码开始:
let g = fun n -> n + 4;;
这行得通,但我不会使用 fun
将其写为显式函数 - 您也可以使用 let
来定义函数,而且它更简单。此外,在 F# Interactive 中您只需要 ;;
,但如果您使用任何带有命令的合适编辑器将代码发送到 F# interactive(通过 Alt+Enter),则不需要它。
但是,在您的 f
函数中,您想要 return float
因此您也需要将 g
修改为 return 浮动。这意味着将 4
替换为 4.0
:
let g n = n + 4.0
h
函数很好,但是你可以用let
重新写:
let h (x,y) = System.Math.Sqrt((x*x)+(y*y));;
在你的 f
函数中,你可以使用 function
来编写一个使用模式匹配的函数,或者你可以使用更详细的语法 match
(function
只是一个 shorthand 用于编写函数然后在输入上进行模式匹配):
let f = function
| (n,0.0) -> g(n)
| (x,n) -> h(x,n)
let f (x, y) =
match (x, y) with
| (n,0.0) -> g(n)
| (x,n) -> h(x,n)
另请注意缩进很重要 - |
之前需要空格。
我将处理您的第一段代码,斐波那契函数留待以后处理。先转一下你的代码,再说吧
let g = fun n -> n + 4;;
let h = fun (x,y) -> System.Math.Sqrt((x*x)+(y*y));;
let f = fun (x,n) -> float
|(n,0) -> g(n)
|(x,n) -> h(x,n);;
第一条评论:如果您正在定义一个函数并立即将其分配给一个名称,就像在所有这些示例中一样,您不需要 fun
关键字。通常定义函数的方式是写成let (name) (parameters) = (function body)
。所以你上面的代码将变成:
let g n = n + 4;;
let h (x,y) = System.Math.Sqrt((x*x)+(y*y));;
let f (x,n) = float
|(n,0) -> g(n)
|(x,n) -> h(x,n);;
我没有做任何其他更改,所以您的 f
函数仍然有错误。接下来让我们解决该错误。
我认为您在这里犯的错误是认为 fun
和 function
可以互换。他们不是。 fun
是标准函数定义,但 function
是另外一回事。在 F# 中编写如下函数是一种非常常见的模式:
let someFunc parameter =
match parameter with
| "case 1" -> printfn "Do something"
| "case 2" -> printfn "Do something else"
| _ -> printfn "Default behavior"
function
关键字是shorthand一个参数加一个匹配表达式。换句话说,这个:
let someFunc = function
| "case 1" -> printfn "Do something"
| "case 2" -> printfn "Do something else"
| _ -> printfn "Default behavior"
与此完全相同的代码:
let someFunc parameter =
match parameter with
| "case 1" -> printfn "Do something"
| "case 2" -> printfn "Do something else"
| _ -> printfn "Default behavior"
只有一处不同。在带有 function
关键字的版本中,您无法选择参数的名称。它由 F# 编译器自动创建,并且由于您无法提前知道参数的名称,因此您无法在代码中引用它。 (好吧,有很多方法,但我不想让你在学会走路之前就学会 运行,可以这么说)。还有一件事:当您仍在学习 F# 时,我强烈建议您不要使用 function
关键字。一旦您知道自己在做什么,它就非常有用,但在您的早期学习阶段,您应该使用更明确的 match (parameter) with
表达式。这样你就会习惯于看到它在做什么。一旦您使用 F# 几个月,就可以开始用更短的 let f = function (...)
替换那些 let f param = match param with (...)
表达式。但在 match param with (...)
真正深入理解之前,您应该继续明确地输入它。
所以您的 f
函数应该如下所示:
let f (x,n) =
match (x,n) with
|(n,0) -> g(n)
|(x,n) -> h(x,n);;
我看到当我输入这个时,Tomas Petricek 发布了一个回复,它解决了 float
的不正确用法,所以我不会重复他对你为什么会得到一个f
函数中的 float
字词错误。他还解释了 ;;
,所以我也不会重复。我只想说,当他提到 "any decent editor with command for sending code to F# interactive (via Alt+Enter)" 时,有很多编辑器选择——但作为初学者,您可能只想有人向您推荐一个,所以我会推荐一个。不过,首先:如果您使用 Windows,您可能已经在使用 Visual Studio,在这种情况下,您应该坚持使用 Visual Studio,因为您知道它。它是 F# 的一个很好的编辑器。但是,如果您还没有使用 Visual Studio,我不建议您下载它只是为了玩弄 F#。这是一个程序的野兽,专为专业软件开发人员设计,可以完成他们在工作中需要做的各种事情,因此如果您刚刚开始使用它,可能会感到有点不知所措。所以我实际上会推荐一些更轻量级的东西:编辑器调用 Visual Studio 代码。它是跨平台的,将 运行 在 Linux、OS X 或 Windows 上完美运行。下载并安装 VS Code 后,您将需要安装 Ionide 扩展。 Ionide 是 VS Code 的插件(也适用于 Atom,尽管 Ionide 的 Atom 版本更新频率较低,因为现在所有 Ionide 开发人员都使用 VS Code),这使得 F# 编辑成为一种真正的乐趣。实际上,您会发现三个扩展:Ionide-fsharp、Ionide-FAKE 和 Ionide-Paket。下载并安装这三个工具:FAKE 和 Paket 是两个您可能不需要的 F# 编程工具,但是一旦您需要它们,您就已经安装了它们。
好的,我想这足以让你开始了。