f# - 如何在 VisualStudio *.fsx 中格式化多行 F# 函数
问题描述
Q1:我想在 Visual Studio 2019 的 *.fsx 中跨多行格式化 F# 函数,但尝试时出现语法错误。(见下文。)
Q2:在 Haskell 中(我记得)你声明函数的顺序并不重要。在 F# 中也是如此吗?
(*
2.3 Declare the F# function
isIthChar: string * int * char -> bool
where the value of isIthChar(str,i,ch) is true
if and only if ch is the i’th character in the string str
(numbering starting at zero).
Hansen, Michael R.. Functional Programming Using F# (p. 39). Cambridge University Press. Kindle Edition. *)
let isIthChar (str: string, i, ch) = (ch = str.[i])
(*
2.4 Declare the F# function
occFromIth: string * int * char -> int where
occFromIth(str, i, ch) =
the number of occurances of character ch
in positions j in the string str
with j >= i
Hint: the value should be 0 for i ≥ size str.
Hansen, Michael R.. Functional Programming Using F# (p. 39). Cambridge University Press. Kindle Edition.
*)
let rec countChar(str, i, j, ch, cnt) = if j < i then cnt else if isIthChar(str, j, ch) then countChar(str, i, j - 1, ch, cnt + 1) else countChar(str, i, j - 1, ch, cnt);; // all one line
let occFromIth(str, i, ch) = if (i >= String.length str) then 0 else countChar(str, i, (String.length str) - 1, ch, 0);; // all one line
//WANT something like:
let rec countChar(str, i, j, ch, cnt) = if j < i
then cnt
else if isIthChar(str, j, ch)
then countChar(str, i, j - 1, ch, cnt + 1)
else countChar(str, i, j - 1, ch, cnt);;
let occFromIth(str, i, ch) = if (i >= String.length str)
then 0
else countChar(str, i, (String.length str) - 1, ch, 0);;
// but these give syntax errors.
(* 2.5 Declare the F# function occInString: string * char -> int where
occInString(str, ch) = the number of occurences of a character ch in the string str.
Hansen, Michael R.. Functional Programming Using F# (p. 39). Cambridge University Press. Kindle Edition. *)
let occInString(str, ch) = occFromIth(str, 0, ch)
解决方案
Formatting: then
andelse
必须至少与它们之前的右边一样远if
,但在这两种情况下,它们都在左边。只需移动if
下一行:
let rec countChar(str, i, j, ch, cnt) =
if j < i
then cnt
else if isIthChar(str, j, ch)
then countChar(str, i, j - 1, ch, cnt + 1)
else countChar(str, i, j - 1, ch, cnt)
fsx
另请注意,如果代码位于文件中而不是从键盘输入 FSI,则不需要双分号。
声明顺序:与 Haskell 不同,在 F# 中,所有名称都必须在使用前定义,因此您的程序从上到下读取。起初这似乎是有限的,但在实践中它确实为代码的可读性创造了奇迹。
此规则的一个例外是一组相互递归的函数(或类型):
let rec f x = g (x+1)
and g x = f (x-1)
在这个例子g
中是在定义之前使用的。
最近 F# 也有了递归模块,其中所有的定义都被认为是一个大的递归组:
module rec A =
let f x = g (x+1)
let g x = f (x-1)
一些与您的问题不严格相关的注释:
else if
可以缩写elif
- 虽然可以将参数定义为 tuple
countChar(str, i, j, ch, cnt)
,但习惯上(并且在实践中更方便)以咖喱形式定义它们countChar str i j ch cnt
推荐阅读
- java - Java - 按换行符分割文件
- angular - AuthGuard 错误:无法从同步测试中调用 Promise.then
- sql - Postgres 查询中的逻辑
- python - 如何在字典中更新列表中的值?
- javascript - 联系表格 7 和 Cleave.js。电话号码输入栏
- arduino - 我如何使用字符串作为 pinname(nodemcu 板)
- console-application - 为什么 ANSI 转义码不能正确显示?
- c++ - c++ 中的每个对象是否包含不同版本的类成员函数?
- c++ - 为什么在 new 运算符的情况下会自动调用析构函数?
- node.js - 为什么节点快递在第一次请求后发送不同的标头