Что такое полиморфизм легкомыслия
как следует из названия вопроса, я хочу знать, что такое полиморфизм легкомыслия и какова его мотивация ? Я знаю на этой странице есть некоторые детали в нем, но большинство объяснений там идут поверх моей головы. :)
пока на этой странице немного дружелюбнее, я все еще не могу понять мотивацию этого.
1 ответ:
Примечание: этот ответ основан на очень недавних наблюдениях за легкомысленными дискуссиями. Все, что касается полиморфизма легкости, в настоящее время реализуется только в кандидатах на выпуск GHC 8.0 и как таковой может быть изменено (см. #11471 например).
TL; DR: это способ сделать функции полиморфными над поднятыми и не поднятыми типами, что невозможно с регулярными функциями. Например, следующий код не тип проверки с регулярными полиморфизмами, так как
Int#имеет вид#, но переменные типа вidимеет вид*:{-# LANGUAGE MagicHash #-} import GHC.Prim example :: Int# -> Int# example = id -- does not work, since id :: a -> aCouldn't match kind ‘*’ with ‘#’ When matching types a0 :: * Int# :: # Expected type: Int# -> Int# Actual type: a0 -> a0 In the expression: idобратите внимание, что
(->)все еще использует магию.
прежде чем я начну отвечать на этот вопрос, давайте сделаем шаг назад и перейти к одному из наиболее часто используемых функций,
($).что это 'ы? Ну, по Здесь и отчет, это
($) :: (a -> b) -> a -> bоднако, это не 100% полный. Это удобная маленькая ложь. Проблема в том, что полиморфные типы (например,
aиb) имеют вид*. Однако разработчики (библиотеки) хотели использовать($)не только для типов вроде*, но и для тех, кто из рода#, например,unwrapInt :: Int -> Int#пока
Intимеет вид*(это может быть нижняя часть),Int#имеет вид#(и не может быть дна у всех). Тем не менее, следующий код typechecks:unwrapInt $ 42это не должно работать. Помните возвращаемый тип
($)? Он был полиморфным, а полиморфные типы имеют вид*, а не#! Так почему же это сработало? Во-первых, это было ошибка, а потом это было hack (цитата из письмо Райана Скотта в списке рассылки ghc-dev):так почему же это происходит?
длинный ответ заключается в том, что до GHC 8.0, в типе подпись
($) :: (a -> b) -> a -> b,bна самом деле не в натуре*, аOpenKind.OpenKind- это ужасный хак, который позволяет как поднял (вроде*) и на месте (типа#) типы, чтобы населить его, вот почему(unwrapInt $ 42)проверка типов.так что
($)новый тип в GHC 8.0? Это($) :: forall (w :: Levity) a (b :: TYPE w). (a -> b) -> a -> b -- will likely change according to Richard E.чтобы понять это, мы должны посмотреть
Levity:data Levity = Lifted | Unliftedтеперь, мы можем думать о
($)как имеющий один из следующих типов, так как есть только два вариантаw:-- pseudo types ($) :: forall a (b :: TYPE Lifted). (a -> b) -> a -> b ($) :: forall a (b :: TYPE Unlifted). (a -> b) -> a -> b
TYPEэто магическая константа, и она переопределяет виды*и#какtype * = TYPE Lifted type # = TYPE Unliftedколичественная оценка по видам также довольно новый и часть интеграция зависимых типов в Haskell.
имя легкомыслия полиморфизм исходит из того, что теперь вы можете писать полиморфные функции как поднимается и несъемные типы, что-то, что не было разрешено/возможно с предыдущими ограничениями полиморфизма. Он также избавляется от
OpenKindвзломать в то же время. Это действительно" просто " об этом, обрабатывая оба вида видов.кстати, вы не одиноки со своим вопросом. Даже Саймон Пейтон Джонс сказал, что есть необходимость в легкомысленной вики-странице, и Ричард Э. (нынешний исполнитель этого) заявил, что страница Вики нуждается в обновление о текущем процессе.
ссылки
- Полиморфизм Легкомыслия В Зависимом Haskell; выступление Ричарда А. Айзенберга на ICFP 2015. Очень рекомендую.
- полиморфизм легкомыслия (Расширенная версия) Ричард А. Айзенберг и Саймон Пейтон Джонс
GHC.Types, частьghc-primбиблиотека, которая поставляется с GHC.- обсуждения:
- обсуждение ghc-dev.
- обсуждение haskell-cafe.
Comments