Я думаю, вы путаете тип ([(a,b)]
) с шаблонами. В вашей функции isEmpty
вы пишете:
isEmpty::Ord a => [(a,b)] -> Bool
isEmpty <b>[(a,b)]</b> = null [undefined, undefined]
Но это не означает, что вы собираетесь сопоставлять списки типа [(a,b)]
. Вы уже сказали, что в вашем типе подписи. Ваш [(a,b)]
во второй строке означает, что вы определяете шаблон. Шаблон говорит, что вы сопоставляете только списки, которые содержат точно один элемент: 2-кортеж, с a
первым элементом этого кортежа и b
вторым элементом этого кортежа.
Если вы затем передадите ему пустой список или список с двумя или более элементами, шаблон не будет совпадать, и, следовательно, возникнет ошибка.
Если вы хотите сопоставить любой список, вы можете просто использовать переменную:
isEmpty :: Ord a => [(a,b)] -> Bool
isEmpty <b>ls</b> = null <b>ls</b>
здесь isEmpty
, таким образом, вызовет null
с этой переменной. Мы можем выполнить η-сокращение здесь и написать:
isEmpty :: Ord a => [(a,b)] -> Bool
isEmpty = null
Нет необходимости ограничивать себя только списками с 2-мя кортежами, где первый элемент этихТип кортежей является членом класса типов Ord
, однако мы можем разрешить эту работу с любым списком. Таким образом, мы можем обобщить тип следующим образом:
isEmpty :: <b>[a]</b> -> Bool
isEmpty = null
Фактически null
может работать над любым Foldable
, поскольку он имеет тип null :: Foldable f => f a -> Bool
.
Учитывая приведенное выше определение функции, нет необходимости реализовывать свой собственный isEmpty
, вы можете просто позвонить null emptyList
.