How to write startWith list function using active template instead of guarding?

I need to check if the list starts with another shorter list. Function when used when protecting triviality:

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

But all that I tried on the lines of the active template:

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

I could not do the compilation. How to create a version of this function using Active pattern? And if this is not possible, can you explain why?

PS Any other good ways to write this function?

EDIT: I took a snippet from Daniel's answer so as not to be distracted from the real question.

EDIT: My problems started from the very beginning. I defined the active function of the pattern as

let (|HeadsMatch|_|) lst1 lst2 =

but it was supposed to be

let (|HeadsMatch|_|) (lst1, lst2) =

In this case, it will match, as in the accepted answer.

+4
2

, -

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,

let rec startsWith l1 l2 =
  match l1, l2 with
  | [], _ | _, [] -> true
  | HeadsMatch(xs, ys) -> startsWith xs ys
  | _ -> false
+5

:

  • ( , ), (|HeadsMatch|_|).

  • , lst1, lst2.

. , .Head .Tail , , - ; , .

HeadsMatch:

let (|HeadsMatch|_|) (lst1, lst2) =
    match (lst1, lst2) with
    | (x :: xs, y :: ys) when x = y -> Some (xs, ys)
    | _ -> None

:

let (|HeadsMatch|_|) (lst1, lst2) =
    match (lst1, lst2) with
    | (x :: xs, y :: ys) ->
        if x = y then Some (xs, ys) else None
    | _ -> None

. :

startsWith [1;2] [1]

, lst2 , .Head .Tail . , .

+2

Source: https://habr.com/ru/post/1534483/


All Articles