Понимание purescript-варианта - PullRequest
0 голосов
/ 10 декабря 2018

Новичок здесь.Я пытаюсь понять некоторые механизмы, стоящие за purescript-вариантом .По сути, я имею в виду, как понимать эти две функции: inj и on .

Когда я смотрю на тип inj, автор использует Минусы Классы типов.Насколько я понимаю, Cons помещают утверждение, что есть запись r2, которую можно сделать из какой-то другой записи r1, вставив пару тег / значение.Таким образом, в некотором смысле:

r1 + tag/value = r2

И в этом случае Variant является r2.

Ссылаясь на readme:

foo :: forall v. Variant (foo :: Int | v)
foo = inj (SProxy :: SProxy "foo") 42

bar :: forall v. Variant (bar :: Boolean | v)
bar = inj (SProxy :: SProxy "bar") true

fooToString :: forall v. Variant (foo :: Int | v) -> String
fooToString = on (SProxy :: SProxy "foo") show (\_ -> "not foo")

Это гдеэто сбивает с толку для меня.Я могу передать bar в качестве аргумента fooToString, в то время как от типа bar нет гарантии, что у него есть тег "foo", даже если это открытый тип.Как это возможно?

1 Ответ

0 голосов
/ 10 декабря 2018

И foo, и bar ограничивают то, что тип варианта должен содержать какой-либо тег, но они не препятствуют включению других тегов в вариант.Конкретные типы при применении fooToString bar будут следующими:

 bar :: Variant (bar :: Boolean, foo :: Int) -- v = (foo :: Int)
 fooToString :: Variant (foo :: Int, bar :: Boolean) -> String -- v = (bar :: Boolean)

Как вы можете видеть, они идеально совместимы.


Внутренняя версия типов будет

bar :: forall r1 r2. RowCons "bar" Boolean r1 r2 => Variant r2
fooToString :: forall r1 r2. RowCons "foo" Int r1 r2 => Variant r2 -> String

, который будет специализироваться на

bar :: RowCons "bar" Boolean (foo :: Int) (foo :: Int, bar :: Boolean) => Variant (foo :: Int, bar :: Boolean)
fooToString :: RowCons "foo" Int (bar :: Boolean) (foo :: Int, bar :: Boolean) => Variant (foo :: Int, bar :: Boolean) -> String

Где, для bar, r1 устанавливается на / специализируется на (foo :: Int) и r2 становится (foo :: Int, bar :: Boolean).Аналогично для fooToString.

Как видите, r1 не используется вне ограничения как для bar, так и для fooToString, что позволяет свободно выбирать их для удовлетворения ограничений.Было бы одинаково допустимо, чтобы компилятор добавил еще больше (неиспользованных) вариантов к типу, но это не изменило бы результат.


Редактировать:

Что-то, что являетсянеобычным в Pruescript является то, что не только функции, но и значения могут быть полиморфными.В этом случае bar - это полиморфное значение, а fooToString - это полиморфная функция.Это означает, что пользователи как bar, так и fooToString могут свободно выбирать любой тип для v (или r1 / r2), поскольку тип содержит требуемые варианты.

...