fun number_in_month6 (m, (_,d2,_) :: ms) =
List.length (List.filter (fn (_,x2,_) => x2 = m) ms)
: stdIn:279.36 Warning: calling polyEqual
: stdIn:278.5-279.43 Warning: match nonexhaustive
: (m,(_,d2,_) :: ms) => ...
:
: val number_in_month6 = fn : ''a * ('b * ''a * 'c) list -> ('b * ''a * 'c) list
Я не могу понять, почему моя функция не является исчерпывающей и дает неверные ответы.
Не исчерпывающая: существует значение, которое шаблон (_,d2,_) :: ms
не будет совпадать, то есть []
. Кажется, проблема в том, что вы сопоставляете шаблон на входе number_in_month6
вообще, когда вам действительно нужно сделать это только внутри функции предиката для List.filter
.
Возможно, здесь неверное представление о том, что «вход не будет списком из трех кортежей, если я не сопоставлю шаблон в аргументе, так как я удалил аннотации типов ". Может быть интересно знать, что типовой вывод SML достаточно силен, чтобы сделать вывод, что ms
является списком из трех кортежей, просто используя List.filter
и fn (_,month2,_) => ...
.
Bad ответы: иногда результат равен единице, потому что вы отбрасываете первый элемент, (_,d2,_)
, и видите, какова длина отфильтрованного остатка списка, ms
.
В вашем примере первая дата предполагается, что он считается частью правильного результата, 3, но вместо этого он отбрасывается, а оставшиеся 2 из 3 дат учитываются правильно.
Исправление:
fun number_in_month (month1, dates) =
List.length (List.filter (fn (_, month2, _) => month1 = month2) dates)
И тестирование этого:
- number_in_month6 (2,[(2018,2,1),(2018,2,2),(2018,1,3),(2018,2,4)]);
> val it = 3 : int
Некоторые моменты: Если вы называете переменные более точные имена, вам легче понять, что происходит. Вы можете рассмотреть возможность использования записи вместо кортежа. Они в основном одинаковы, за исключением того, что кортежи имеют пронумерованные записи, а записи имеют именованные записи, а синтаксис записей немного сложнее. Но положительным моментом является то, что вы случайно не забудете американские, европейские или ISO даты:
type date = { year : int, month : int, day : int }
fun number_in_month (month1, dates : date list) =
List.length (List.filter (fn ({ month = month2, ... }) => month1 = month2) dates)
val test_1 = number_in_month (2, [ { year = 2018, month = 2, day = 1 }
, { year = 2018, month = 2, day = 2 }
, { year = 2018, month = 1, day = 3 }
, { year = 2018, month = 2, day = 4 }
])
Синтаксис записи может быть немного сложным, так что не стесняйтесь продолжать с кортежами так долго как вы находите их практичными.