У меня простой ADT
data Concept a = Entity a | Role a | Relation a | Resource a | Sub (Concept a)
Теперь я хочу создать GADT, используя этот ADT, который будет ограничивать сигнатуру типа его конструкторов. Этот код не будет работать, но я хочу сделать что-то вроде этого:
data Construct a b where
Has :: Concept a -> 'Resource b -> Construct (Concept a) ('Resource b)
Т.е. Has
конструктор для Construct
может иметь параметр первого типа как Concept
любой формы, но параметр второго типа должен быть конструктором Resource
(повышенным до типа). Эта подпись не работает, поскольку я использую вид вместо типа. Но я хочу осознать нечто подобное и не могу понять, как сделать то же самое.
Я импортирую {-# LANGUAGE GADTs, TypeInType #-}
.
Редактировать:
Основываясь на одном комментарии, если я сделаю это
data Construct (a :: Concept ak) (b :: Concept bk) where
Has :: Construct a ('Resource b)
Тогда это проверка типов. Но теперь как мне извлечь значения при сопоставлении с образцом на Has
f :: Construct a b -> T.Text
f Has = ???
Мое требование: я хочу ограничить типы для конструктора Has a b
, чтобы он мог разрешать только a :: Concept ak
(т.е. любую концепцию) и (b ~ 'Resource *) => (b :: Concept bk)
[1] (т.е. только тип ресурса концепции), например.
-- Concept values
person = Entity "person"
name = Resource "name"
role = Role "father"
-- I want this to be valid
personHasName = Has person name
-- And this to be invalid
personHasRole = Has person role
[1] - После некоторого чтения ограничений в видах, семействах типов и синглтон-типах я думаю, что можно реализовать такого рода ограничения с помощью этих принципов. Но я совершенно не в силах заставить его работать
'Resource
:Has :: Concept a -> Construct (Concept a) ('Resource b)
. Но я предполагаю, что вы хотите, чтобы оба ваших полей были повышены до типов; в этом случае вам нужно что-то вродеHas :: Construct (x :: Concept a) ('Resource b)
; в этом случае вы, вероятно, также захотите объявить kind вашего типа:data Construct (a :: Concept ak) (b :: Concept bk) where Has :: Construct a ('Resource b)
- person user2407038   schedule 24.05.2017Has :: Concept -> Constraint
. Поскольку отношениеHas
не имеет семантики, вам нужно создавать смысл самостоятельно. - person Lazersmoke   schedule 25.05.2017