gpt4 book ai didi

f# - 如何使用 Active Pattern 而不是 when guard 来编写 startsWith 列表函数?

转载 作者:行者123 更新时间:2023-12-04 23:50:47 24 4
gpt4 key购买 nike

我需要检查一个列表是否以另一个较短的列表开头。该函数,当使用 时当守卫是微不足道的:

let rec startsWith l1 l2 =
match l1, l2 with
| [], _ | _, [] -> true
| x::xs, y::ys when x = y -> startsWith xs ys
| _ -> false

let lst1 = [ 1; 2; 1 ]
let lst2 = [ 1; 2; 1; 2; 3; ]
let lst3 = [ 1; 3; 1; 2; 3; ]

let c1 = startsWith lst1 lst2 // true
let c2 = startsWith lst1 lst3 // false

但是,无论我按照 Active Pattern 的方式尝试过什么:
let (|HeadsMatch|) (l1 : ('a) list) (l2 : ('a) list) = 
if l1.Head = l2.Head then Some(l1.Tail, l2.Tail) else None

let rec startsWith l1 l2 =
match l1, l2 with
| [], _ | _, [] -> true
| HeadsMatch /* need to capture the result */ -> startsWith t1 t2
| _ -> false

我无法编译。如何使用 Active 模式制作此功能的版本?如果这是不可能的,你能解释一下原因吗?

附注编写上述函数的任何其他好方法?

编辑:我从丹尼尔的回答中摘取了片段,以免分散对真正问题的注意力。

编辑:我的问题从一开始就开始了。我已将事件模式函数定义为
let (|HeadsMatch|_|) lst1 lst2 =

但它应该是
let (|HeadsMatch|_|) (lst1, lst2) =

在这种情况下,它将与接受的答案匹配。

最佳答案

我想最好的方法可能是

let startsWith = Seq.forall2 (=)

如果要从头开始编写,则需要在两个列表上进行匹配:
let rec startsWith l1 l2 =
match l1, l2 with
| [], _ | _, [] -> true
| x::xs, y::ys when x = y -> startsWith xs ys
| _ -> false

如果您想使用事件模式编写以用于学习目的,请使用 Tarmil's definition这将是
let rec startsWith l1 l2 =
match l1, l2 with
| [], _ | _, [] -> true
| HeadsMatch(xs, ys) -> startsWith xs ys
| _ -> false

关于f# - 如何使用 Active Pattern 而不是 when guard 来编写 startsWith 列表函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22790841/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com