我有一个带递归函数的函数,用于计算单词中的字母,以便"hello"
返回[|("h",1);("e",1);("l",2);("o",1);|]
。
我的代码如下:
let letterCheck (a:string) =
let aList = a |> Seq.toList;
let rec _check (charList:char list) (result:(char * int) array) =
match charList with
| head :: tail ->
if Array.exists (fun (c,i) -> c = head) result then
let index = Array.findIndex (fun (c,i) -> if c = head then true else false) result;
Array.set result index (result.[index].[1]+1);
else
Array.append result [|(head,1)|];
_check tail result;
| [] -> result;
_check aList [||];
但是即使我输入带注释的结果,它在Array.set
行上也出现错误并显示错误:
Program.fs(73,45):错误FS0752:运算符'expr。[idx]'已根据此程序点之前的信息用于不确定类型的对象。考虑添加其他类型约束。
如何解决此错误或我做了一些根本错误的事情?
答案 0 :(得分:3)
我在做一些根本错误的事情吗?
此代码看起来似乎期望使用可变值:
if Array.exists (fun (c,i) -> c = head) result then
let index = Array.findIndex (fun (c,i) -> if c = head then true else false) result;
Array.set result index (result.[index].[1]+1);
else
// new array value will be discarded
Array.append result [|(head,1)|];
_check tail result; // result will be unchanged
Array.append
返回修改后的数组值;它不会改变输入数组的值。 result.[index].[1]+1
看起来你正在尝试使用数组索引语法从元组中获取第二项(而不是使用snd
),但即使修复了这个函数仍会出现问题,因为它&# 39; ll总是以result
的相同/不变值递归。
此外,您不需要在F#中以分号结束每一行。
这是您的函数版本,只需最少的更改,无需额外的类型注释:
let letterCheck (a:string) =
let aList = a |> Seq.toList
let rec _check charList result =
match charList with
| head :: tail ->
if Array.exists (fun (c,i) -> c = head) result then
let index = Array.findIndex (fun (c,i) -> c = head) result
Array.set result index (head, (snd(result.[index])+1))
_check tail result
else
_check tail (Array.append result [|(head,1)|])
| [] -> result
_check aList [||]
> letterCheck "hello";;
val it : (char * int) array = [|('h', 1); ('e', 1); ('l', 2); ('o', 1)|]
或者从中获取所有乐趣:
"hello" |> Seq.countBy id