Я только что закончил читать статью Политизма Левита.
У меня возник вопрос о том, почему 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 типа? Неужели я что-то недопонимаю о бумаге (или о боксе или легкомыслии)?