我需要检查一个列表是否以另一个较短的列表开头。当守卫时使用该功能是微不足道的:
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
但是无论我尝试什么活动模式:
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 模式制作此功能的版本?如果这是不可能的,你能解释为什么吗?
PS 还有其他写上述函数的好方法吗?
编辑:我从丹尼尔的回答中摘录了片段,以免分散真实问题的注意力。
编辑:我的问题从一开始就开始了。我已将活动模式功能定义为
let (|HeadsMatch|_|) lst1 lst2 =
但它应该是
let (|HeadsMatch|_|) (lst1, lst2) =
在这种情况下,它将与接受的答案一样匹配。