У вас есть несколько проблем.Во-первых, вы используете сопоставление с образцом, чтобы проверить, является ли список точно [y]
.Это не то, как это работает, это будет фактически соответствовать любому списку с ровно одним элементом.Если вы хотите указать такие равенства, вы можете использовать предложения when
.
let rec contains (l : int list) (y : int) : bool =
begin match l with
| [] -> false
| [z] when z = y -> true
| [z] -> false
| hd :: tl -> hd = y && contains tl y
end
Первые [z] when z = y
сработают в списке, содержащем именно ваш y
.Второе предложение [z]
сработает по остальным.
Затем возникает проблема вашего последнего случая: y
принадлежит hd :: tl
, если это hd
или если он принадлежит tl
.Вы использовали и , так что это не могло быть правильно.Это дает нам:
let rec contains (l : int list) (y : int) : bool =
begin match l with
| [] -> false
| [z] when z = y -> true
| [z] -> false
| hd :: tl -> hd = y || contains tl y
end
Конечно, это даже можно упростить.
let rec contains (l : int list) (y : int) : bool =
begin match l with
| [] -> false
| hd :: tl -> hd = y || contains tl y
end
Действительно, нет необходимости создавать особый случай списка с одним элементом.[y]
совпадает с y :: []
.
Итак, если подвести итог, если элемент находится в голове, вы его получили, в противном случае вы идете смотреть в хвост и так далее, пока не достигнете пустогосписок, который означает, что вы не нашли его.