AppendedList a
это тип.
AList f
- это тип данных с некоторой функцией f :: [a] -> [a]
"внутри него".
f
- это функция от списков к спискам с элементами одного типа.
Мы можем назвать это с some_list :: [a]
, чтобы получить resulting_list :: [a]
:
f :: [a] -> [a]
some_list :: [a]
-------------------------
f some_list :: [a]
resulting_list :: [a]
resulting_list = f some_list
Мы можем использовать resulting_list
в качестве some_list
тоже, т.е.
resulting_list = f resulting_list
, потому что он имеет тот же тип, который соответствует ожиданиям f
(и из-за лени Haskell). Таким образом,
toList (...) = let { ... = ... }
in ...
является одним из возможных определений. При этом
take 2 (toList (single 5))
вернет [5,5]
.
edit: Конечно [5,5]
не является списком, содержащим single 5. Более того, take 4 ...
вернет [5,5,5,5]
, поэтому наше представление содержит любое количество пятерок, а не только одну из них. Но он содержит только одно отдельное число, 5.
Это напоминает два экземпляра Applicative Functor для списков, []
и ZipList
. pure 5 :: [] Int
действительно содержит только одну пятерку, но pure 5 :: ZipList Int
содержит любое количество пятерок, но только пятерок. Конечно, сложно добавлять бесконечные списки, так что в основном это просто любопытство. Пища для размышлений.
В любом случае это показывает, что есть не просто один способ написать код, который проверяет здесь тип. В нашем распоряжении больше, чем один список. Самый простой из них - это действительно []
, а другой ... сам наш список!