В первом типе:
data List t = E | C t (List t)
t
является параметром типа, он должен быть представлен в качестве существующего типа. E
не является типом, это конструктор данных, или значение конструктор. C
также является конструктором данных. Они имеют типы:
E :: List t
C :: t -> List t -> List t
Можно построить значения, как
> E :: List Int -- Equivalent to []
E
> C 1 E :: List Int -- Equivalent to [1]
C 1 E
> C 1 (C 2 E) :: List Int -- Equivalent to [1, 2]
C 1 (C 2 E)
И так далее. Вы можете обрабатывать E
как пустой список []
и C
как конструктор списка :
, поэтому C 1 (C 2 (C 3 E))
эквивалентен 1 : 2 : 3 : []
, который совпадает с [1, 2, 3]
.
Во втором типе:
data NonEmptyList a = NEL a [a]
У вас есть конструктор данных
NEL :: a -> [a] -> NonEmptyList a
Вы можете построить значения как
> NEL 1 [] :: NonEmptyList Int -- Equivalent to [1]
NEL 1 []
> NEL 1 [2] :: NonEmptyList Int -- Equivalent to [1, 2]
И так далее. Этот тип заставляет вас всегда иметь хотя бы одно значение, поэтому оно не может быть не пустым.
Когда вы пишете lst2 :: NonEmptyList = 2
, это ошибка синтаксиса, и это трудно догадаться, что вы имели в виду, но эквивалент NonEmptyList Int
к lst1 :: List Int
будет написано как NEL 2 [] :: NonEmptyList Int
.