list - 在 F# 中声明类型列表参数

标签 list f#

我正在构建一个比较两个列表的简单函数,如果第一个列表是第二个列表的前缀,则返回 true。 预期签名:

prefix: int list -> int list -> bool

例如:

prefix [1; 2] [1; 2; 3; 4] --> true
prefix [ ] [1;2] --> true
prefix [2] [1;2;3] --> false

现在,我正处于这一步:

let prefix l1 l2 =
        match l1 with
        | (l1, l2) when (l1.[0] = l2.[0]) -> true
        | _ -> false 

我认为我的方法可能是正确的,但我遇到了这个错误:

 The operator 'expr.[idx]' has been used on an object of
    indeterminate type based on information prior to this program point. Consider adding 
    further type constraints

如何在 prefix 中声明 l1l2 是列表?我寻找解决方案 here但问题可能是如此微不足道,以至于我没有答案。

最佳答案

为了回答关于声明类型是列表的问题的最后一部分(因为其他部分已经回答),我们使用“类型注释”。它们在函数参数中看起来像 (name : type),例如

let prefix (l1 : _ list) (l2 : _ list) = ...

这会将 l1l2 声明为编译器将推断的某种类型的列表。您也可以根据需要将 _ 替换为特定类型或通用类型。

要手动实现您的功能,请记住您需要做的不仅仅是比较第一个元素 - 您需要递归遍历列表。

let prefix l1 l2 =
    let rec loop = function
        | [], _ -> true
        | _, [] -> false
        | h1 :: _, h2 :: _ when h1 <> h2 -> false
        | _ :: t1, _ :: t2 -> loop (t1, t2)
    loop (l1, l2)

这个版本根本不需要类型注释,因为 loop 中的模式匹配将两个参数都限制为 'a list 类型。但是,如果您希望您的函数明确地只用于 int list,您可以改为使用

来启动它
let prefix (l1 : int list) l2 =

您只需要注释一个参数,因为另一个参数被限制为同一类型。

关于list - 在 F# 中声明类型列表参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40572925/

相关文章:

python - 如何检查列表内列表的唯一性?

f# - 当方法具有返回值时,如何在 F# 中提供 Expression<Action<T>>?

F#如何传递等效的接口(interface)

f# - 从概念上为 C# 中的 F# 约会创建受歧视联合

f# - 如何从函数中删除命令式代码?

python - 在 Pandas 查询中使用列表

java - 为什么我的 Java 程序忽略另一个 html 中的列表?

python - 为什么这个 3 行程序返回 None 作为输出?

python - 包含多个条件的列表

f# - 错误 FS0001 : The type 'int' does not match the type 'float'