注释变量时F#indeterminate类型错误

时间:2018-02-24 23:09:23

标签: f#

我有一个带递归函数的函数,用于计算单词中的字母,以便"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]'已根据此程序点之前的信息用于不确定类型的对象。考虑添加其他类型约束。

如何解决此错误或我做了一些根本错误的事情?

1 个答案:

答案 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