F#:尝试从函数返回结果时键入类型不匹配错误

时间:2018-09-27 17:33:47

标签: f# type-mismatch

所以我有这个函数,可以计算给定字符串中每个字母的频率百分比。此函数称为“频率”,它利用了我编写的其他辅助函数(“计数”,“ lowerCases”和“百分比”)。但是,当我尝试返回结果时,总是出现不匹配错误。这是我的代码如下:

let frequency(str:string) : float  = 
    let myList = ['a'..'z']
    for i=0 to 25 do 
      printf "%f" (percent ((count myList.[i] str) (lowerCases str)))

System.Console.WriteLine(frequency"hello world")

我不断收到此错误:

This expression was expected to have type float but here has type unit

如何解决此类型的不匹配错误?我已经尝试将结果设置为其他变量并调用该变量,但这没用。

2 个答案:

答案 0 :(得分:1)

您已将该函数声明为返回浮点数:

let frequency(str:string) : float  = 

但是,您的函数不会返回浮点数,只会输出浮点数:

printf "%f" (percent ((count myList.[i] str) (lowerCases str)))

printf函数返回unit,这意味着它实际上没有返回值(它具有单例类型unit的恒定返回值)。

我认为您需要在此处修复两件事。您需要从函数返回一个值(通过使其为最后​​一行的值),我想您希望返回类型为列表或映射,而不是单个值(否则,您怎么知道频率适用哪两个字母?

仅通过从percent调用List.map函数,然后在列表中加入Map,即可达到此结果:

let frequency(str:string) : Map<char, float>  = 
    ['a'..'z']
    |> List.map (fun letter -> letter, (percent ((count letter str) (lowerCases str))))
    |> Map.ofList

答案 1 :(得分:1)

F#函数将单个表达式的单个值绑定到其主体中(简单地说,这是所有let绑定之后的最后一个。在您的情况下,此表达式为

for i=0 to 25 do 
  printf "%f" (percent ((count myList.[i] str) (lowerCases str)))

它的类型为unit,表示它不返回任何有用的值,而是一个特殊值(),而let frequency ... : float =绑定则表示它返回一个float。因此是错误。

printf已打印到控制台。您想要的可能是

let frequency(str:string) : unit  = 
    let myList = ['a'..'z']
    for i=0 to 25 do 
      printf "%f" (percent ((count myList.[i] str) (lowerCases str)))

do frequency "hello world"

在这样的函数中省略: unit注释,让编译器推断返回类型是惯用法。这段代码自然不会给F#带来荣耀,但确实可以做到。

您似乎正在学习该语言,这是一项练习,也许是为了将来。您的函数将计算字母频率和打印集中在一起,而函数式编程全都与构图有关。如果要在窗口中显示结果而不是将结果打印到控制台或以其他方式设置格式怎么办?尝试编写两个函数,一个返回带有字母频率的数据结构,另一个打印它。