Я только что закончил читать статью Политизма Левита.
У меня возник вопрос о том, почему undefined может быть levity-polymorphic, когда используется как unboxed type.
Во-первых, давайте начнем с некоторых определений бокса из статьи:
-
в коробке:
-
Коробчатое значение представлено указателем на кучу.
-
IntиBoolявляются примерами типов, которые имеют значения в коробке.
-
-
unboxed:
Далее следует статья с некоторыми определениями легкомыслия:
-
снято:
-
Поднятый тип - это ленивый.
-
Поднятый тип имеет дополнительный элемент за пределами обычных, представляющий собой не завершающий вычисление.
-
Например, тип
Boolподнимается, что означает, что дляBoolесть три разных значения:True,Falseи⊥(внизу). -
Все поднятые типы ДОЛЖНЫ быть в коробке.
-
-
unlifted
-
Неперекрытый тип - это строгий.
-
Элемент
⊥не существует в незанятом типе. -
Int#иChar#являются примерами несвязанных типов.
-
Далее в документе объясняется, как GHC 8 обеспечивает функциональность, позволяющую переменным типа иметь полиморфную легкость.
Это позволяет вам написать levity-polymorphic undefined со следующим типом:
undefined :: forall (r :: RuntimeRep). forall (a :: TYPE r). a
Это говорит о том, что undefined должен работать для любых RuntimeRep, даже не связанных типов.
Ниже приведен пример использования undefined как unboxed, unifted Int# в GHCi:
> :set -XMagicHash
> import GHC.Prim
> import GHC.Exts
> I# (undefined :: Int#)
*** Exception: Prelude.undefined
Я всегда думал о undefined как о том же, что и ⊥ (внизу). Однако в документе говорится: "Элемент ⊥ не существует в несимметричном типе".
Что здесь происходит? Является undefined фактически не ⊥ при использовании в качестве unlifted типа? Неужели я что-то недопонимаю о бумаге (или о боксе или легкомыслии)?