f# System.Char.ToUpper

Posted

技术标签:

【中文标题】f# System.Char.ToUpper【英文标题】: 【发布时间】:2017-07-07 18:01:02 【问题描述】:

我有一个练习,要求一个函数使用

将字符串的所有字符转换为大写
System.Char.ToUpper

所以首先我把字符串改成char数组,再把数组改成char列表

let x = s.ToCharArray()
List.ofArray x

接下来,我想我会使用 List.iter 来遍历我的列表并对每个字符使用 System.Char.ToUpper 函数。

List.iter (fun z -> (System.Char.ToUpper(z)))

但这不起作用。我收到一个错误“表达式应该有单位,但这里有字符。”我究竟做错了什么?是逻辑缺陷还是语法缺陷?

【问题讨论】:

【参考方案1】:

这需要一些拆包。

首先,你的核心错误:System.Char.ToUpper 是一个函数。它需要一个字符并返回另一个字符。它不会以某种方式将其参数“更新”为新值。

let x = 'a'
let y = System.Char.ToUpper x  // y = 'A', x = 'a'.

在上面的代码中,我给函数的结果命名为yy 的值为'A',但x 的值仍为'a'。调用函数后,x 没有变化。

从这个错误开始,其余的一切都随之而来。

第二List.iter 是一个函数,对于列表的每个元素,它都会“发生”一些事情。它不会替换列表中的每个元素,也不会创建新列表。它只是让每个元素发生一些事情。这种“something”的最简单示例是打印到控制台:

List.iter (fun x -> printfn "%i" x) [1; 2; 3]  // Prints "1", then "2", then "3"

请注意,此函数有两个参数:表示需要发生的某事的函数,以及从中获取元素的列表。在您的问题中,您似乎缺少第二个论点。 List.iter 怎么知道要使用哪个列表?

List.iter 的第一个参数需要是返回unit 的函数。这是 F# 中的一种特殊类型,基本上表示“无价值”。当一个函数没有返回值时,这意味着调用它的唯一原因是让一些外部的事情发生(在函数式编程中称为“副作用”)。这就是List.iter 要求函数返回unit 的原因——它是对意外提供错误函数的额外保护,就像你所做的那样,实际上:你提供的函数返回char。这就是您收到错误消息的原因。

第三,就像ToUpper 一样,调用List.ofArray 不会以某种方式“更新”x 成为一个列表。相反,它返回一个列表。如果你不给返回的列表命名,它就会丢失。这意味着您调用List.ofArray 的方式是徒劳的。

您真正需要的是 (1) 获取字符串中的字符序列,然后 (2) 将其转换为每个字符为大写的新序列,然后 (3) 粘合这些字符重新组合在一起以获得一个新字符串。

步骤 (1) 是无操作的,因为 .NET 字符串已经是字符序列(即它们实现了IEnumerable<char>)。步骤 (2) 通过称为Seq.map 的通用操作完成。这是一种通过将给定函数应用于每个元素来将序列转换为新序列的操作。在这种情况下,“给定函数”将是 System.Char.ToUpper。步骤 (3) 可以通过String.concat 完成,但您需要先将每个字符转换为字符串,因为String.concat 接受的是字符串序列,而不是字符。

let chars = s
let upperChars = Seq.map System.Char.ToUpper chars
let strChars = Seq.map string upperChars
let result = String.concat "" strChars

或者这可以用更短的方式完成,不需要给每个步骤的结果一个单独的名称,而是通过管道将每个结果直接传递到下一个操作:

let result = 
  s
  |> Seq.map System.Char.ToUpper
  |> Seq.map string
  |> String.concat ""

最后,其实还有一个更短的方法可以做到,但是太明显了,感觉像是在作弊。

问题是,因为字符串是序列,所以它们具有所有序列操作是有意义的。你猜怎么着?他们是这样!具体来说,有一个函数String.map,它和Seq.map做同样的事情,但是对于字符串:

let result = String.map System.Char.ToUpper s

【讨论】:

感谢您花时间向我解释所有这些。我对 f# 非常陌生,我敢肯定你能看出来。 如果您是新手,这里有一个很棒的资源可供开始:fsharpforfunandprofit.com

以上是关于f# System.Char.ToUpper的主要内容,如果未能解决你的问题,请参考以下文章

如何求解:f(n) = f(n-1) + 3*f(n-2) + 3*f(n-3) + f(n-4)

C# 练习用函数递归计算 f(n)=f(n-1)+f(n-2) f=2 f=3

C# 练习用函数递归计算 f(n)=f(n-1)+f(n-2) f=2 f=3

C# 练习用函数递归计算 f(n)=f(n-1)+f(n-2) f=2 f=3

C# 练习用函数递归计算 f(n)=f(n-1)+f(n-2) f=2 f=3

创建一个视图