Представляет набор как функцию, которая, учитывая Int
, сообщает вам, находится ли он в et (возвращая True
) или нет (возвращая False
).
Таким образом, пустой набор - это функция, которая возвращает False
независимо от того, какой аргумент вы указали.
Вставка в набор означает возврат нового набора / функции на основе старого набора / функции.
В вашем определении функции есть небольшая опечатка, так как отсутствует ключевое слово if
:
insert :: Int -> IntSet -> IntSet
insert x s = \y -> if x == y then True else s y
Когда вы вставляете какое-то новое значение x
в набор, вы получаете новый набор, возвращающий True
, если запрашивается только что вставленное значение, либо откладывает ответ на старый набор. Например,
let newset = insert 3 empty in newset 3
оценивается как True
, потому что
newset 3 == (insert 3 empty) 3
== (\y -> if 3 == y then True else empty 3) 3
== if 3 == 3 then True else empty 3
== True
, в то время как let newset = insert 3 empty in newset 4
возвращает False
, потому что
newset 4 == (insert 3 empty) 4
== (\y -> if 3 == y then True else empty 3) 4
== if 4 == 3 then True else empty 3
== empty 3
== (\_ -> False) 3
== False
Это прекрасно работает (хотя и немного неэффективно) для запроса определенного значения. Но что, если вы просто хотите увидеть все значения, содержащиеся в наборе? Концептуально это легко (поскольку Int
конечно, так же как и все возможные наборы): просто отфильтруйте список всех значений Int
, используя набор / функцию:
setToList :: IntSet -> [Int]
setToList s = filter s [minBound..maxBound]
Учитывая что-то вроде setToList (insert 3 (insert 5 empty))
, просто (хотя и утомительно) показать, что
(insert 3 (insert 5 empty)) minBound
Неверно,
(insert 3 (insert 5 empty)) (minBound + 1)
Неверно,
- ...
(insert 3 (insert 5 empty)) 0
Неверно,
(insert 3 (insert 5 empty)) 1
Неверно,
(insert 3 (insert 5 empty)) 2
Неверно,
(insert 3 (insert 5 empty)) 3
верно,
и т.д.
так что конечным результатом будет список [3, 5]
. Однако это занимает некоторое время, поскольку в зависимости от вашей системы список [minBound..maxBound]
может содержать довольно много элементов. (Проверьте значения minBound :: Int
и maxBound :: Int
, чтобы узнать, сколько их.)
Обратите внимание, что setToList
завершается только потому, что Int
- конечный тип.