Почему Haskell Pipes "использует () для закрытия неиспользуемых входов и X (необитаемый тип) для закрытия неиспользуемых выходов"?
В учебнике по трубам говорится, что:
Конкретный тип синонимов использования
()
закрыть неиспользуемые входы иX
(необитаемый тип), чтобы закрыть неиспользуемые выходы:
Я хотел бы понять, почему ()
а также X
используются такими, какие они есть. Почему бы и нет X
или же ()
для обоих входов и выходов?
2 ответа
X
в трубах обычно пишется Void
в остальной части экосистемы Haskell, поэтому давайте представим, X = Void
, Это определяется так:
data Void
И у него есть "элиминатор"
absurd :: Void -> a
absurd x = case x of {}
Если у вас есть что-то типа Void
(и принудительно), тогда что-то пошло не так. Ваша программа выдала ошибку, или она застряла в бесконечном цикле.
Изготовление трубы производит вещи типа Void
запрещает ему когда-либо производить что-либо (законное). Заставить его производить вещи типа ()
позволяет производить вещи, но не несет информации. Они в основном тиканье часов.
На входной стороне труба, которая потребляет вещи типа Void
может ждать ввода, но как только он это сделает, он застрянет - никто не сможет ничего кормить. Труба, которая потребляет вещи типа ()
может ждать, но только получает тики часов.
Все эти варианты являются разумными. Я подозреваю, что Гонсалес хотел, чтобы система типов не позволяла пользователям случайно подключить чистого производителя к чистому потребителю в неправильном направлении и получить ошибку, которую трудно отследить. Заставляя чистого производителя потреблять ()
и чистый потребительский продукт Void
Он делает невозможным подключить их неправильно.
Это на самом деле более общая вещь, чем просто для труб. ()
а также X
являются начальными и конечными объектами категории Hask (и категорий, производных от Hask), что означает, что для всех типов Haskella
,
- существует ровно один морфизм
a -> ()
(а именноconst ()
) - существует ровно один морфизм
X -> a
(а именноabsurd
).
Как следствие, любая цепочка функций a -> ()
>>>() -> b
на самом деле не может зависеть от левой части (так как a -> ()
не несет никакой информации), и любая цепь a -> X
>>>X -> b
не может зависеть от правильной части. В этом смысле () -> b
вход закрыт, и поэтому a -> X
выход.