Объединение списков вариантов разных типов в purescript
Я играл с Purescript как средством экспериментов с программированием на языке, подобном Haskell, с полиморфизмом строк и столбцов.
В частности, используя вариантный пакет Purescript, я пытался написать операцию для последовательного объединения двух списков "примечаний", где два списка, возможно, имеют непересекающиеся наборы вариантов. Идея здесь состоит в том, чтобы позволить пользователям иметь возможность комбинировать оценки, объявленные в некотором подмножестве заметок, для автоматического объединения с оценками, содержащими супернабор, без каких-либо явных преобразований.
Например, учитывая следующий шаблон, чтобы упростить работу с вариантами:
import Data.Variant
import Prim.Row
data A = A
data B = B
data C = C
data D = D
data E = E
data F = F
data G = G
data H = H
_A = SProxy :: SProxy "_A"
_B = SProxy :: SProxy "_B"
_C = SProxy :: SProxy "_C"
_D = SProxy :: SProxy "_D"
_E = SProxy :: SProxy "_E"
_F = SProxy :: SProxy "_F"
_G = SProxy :: SProxy "_G"
Я могу определить следующие типы:
type CNatural = Variant (
_A :: A,
_B :: B,
_C :: C,
_D :: D,
_E :: E,
_F :: F,
_G :: G)
type CPentatonic = Variant (
_A :: A,
_C :: C,
_D :: D,
_E :: E,
_G :: G)
Учитывая это, я могу определить две оценки:
score1 :: Array CPentatonic
score1 = [inj _A A,inj _C C]
score2 :: Array CNatural
score2 = [inj _C C, inj _B B]
Итак, чтобы объединить их, мне нужна функция подписи
combine :: forall v w u. Union w v u =>
Array (Variant v)
-> Array (Variant w)
-> Array (Variant u)
Однако моя попытка:
combine x y = (map expand x) <> (map expand y)
дает
No type class instance was found for
Prim.Row.Union v2
t3
u4
The instance head contains unknown type variables. Consider adding a type annotation.
Если я попробую изменить
Union v w u
ограничение на
Union w v u
ограничение, ошибка переходит туда и обратно между первыми
map expand
, а второй
map expand
, но ничего из того, что я делаю, похоже, не разрешает оба ограничения, даже если у меня есть
Union v w u
и
Union w v u
ограничение, которое, как я думал, было бы лишним.
Что-то мне не хватает? Можно ли сделать что-то подобное в Purescript с помощью библиотеки вариантов?
1 ответ
Если вы хотите производить
Variant u
используя
expand
вы должны потребовать, чтобы оба
v
и
w
являются подразделами
u
:
module Main where
import Prelude
import Data.Variant (expand, Variant)
import Prim.Row (class Union)
combine :: forall v v_ w w_ u. Union w w_ u => Union v v_ u =>
Array (Variant v)
-> Array (Variant w)
-> Array (Variant u)
combine arr1 arr2 = map expand arr1 <> map expand arr2
Вот рабочая суть, загруженная в try.purescript.