Что такое полиморфизм легкомыслия



как следует из названия вопроса, я хочу знать, что такое полиморфизм легкомыслия и какова его мотивация ? Я знаю на этой странице есть некоторые детали в нем, но большинство объяснений там идут поверх моей головы. :)



пока на этой странице немного дружелюбнее, я все еще не могу понять мотивацию этого.

499   1  

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 -> a
Couldn'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 взломать в то же время. Это действительно" просто " об этом, обрабатывая оба вида видов.

кстати, вы не одиноки со своим вопросом. Даже Саймон Пейтон Джонс сказал, что есть необходимость в легкомысленной вики-странице, и Ричард Э. (нынешний исполнитель этого) заявил, что страница Вики нуждается в обновление о текущем процессе.

ссылки

Comments

    Ничего не найдено.