Я знаю, что []
- это пустой список с типом [a]
Да, но важно понимать, что на самом деле означает «тип [a]
». На самом деле это означает тип forall a . [a]
, то есть это не список элементов какого-то определенного типа «а», а, скорее, при любом выборе типа a
, это список этого типа. В частности, это также может быть список типов кортежей. Таким образом, null
работает так же хорошо со списками кортежей, как со списками любого другого типа.
Чтобы реально увидеть null
в действии с таким списком кортежей, вам просто нужно предоставить один. Например, null [(1,2)]
использует его для списка кортежей. Но в случае пустого списка нет содержимого списка, которым вы бы ограничивали тип. Это может быть либо ясно из контекста, как в
Prelude> [null l | l <- [ [], [(1,2)], [(1,3)] ]]
[True,False,False]
, либо вы можете явно указать его с подписью
Prelude> null ([] :: [(String, Double)])
True