История изменений
Исправление qnikst, (текущая версия) :
поскольку код выше предполагает, что мы возможно можем на лету хотеть добавлять котам свойства, то можно сделать так (в этом примере свойства котов образуют закрытое множество):
data CatProps :: * -> * where
CatName :: CatProps String
CatHeight :: CatProps Int
-- бойлерплейт, который сгенерится TH или руками
vasya = DM.fromList [CatName :=> "Vasya"]
kuzya = DM.fromList [CatName :=> "Kuzya" , CatHeight :=> 5]
*Main> let t = vasya ->| kuzya ->| Z
*Main> (cbHead t) ! CatName
"Vasya"
*Main> CatHeight `DM.lookup` cbHead t
Nothing
*Main> CatHeight `DM.lookup` cbHead (cbTail t)
Just 5
Поддтипирование можно делать через
data SubCat :: * -> * where
CatSurname :: SubCat String
SubCat :: SubCat (DM.DMap CatProps)
Хотя это и не идеальный вариант.
Но в обычном коде можно следовать KISS и не выпендриваться.
P.S. открытые множется без поддтипирования оставляю
Исходная версия qnikst, :
поскольку код выше предполагает, что мы возможно можем на лету хотеть добавлять котам свойства, то можно сделать так (в этом примере свойства котов образуют закрытое множество):
data CatProps :: * -> * where
CatName :: CatProps String
CatHeight :: CatProps Int
-- бойлерплейт, который сгенерится TH или руками
vasya = DM.fromList [CatName :=> "Vasya"]
kuzya = DM.fromList [CatName :=> "Kuzya" , CatHeight :=> 5]
*Main> let t = vasya ->| kuzya ->| Z
*Main> (cbHead t) ! CatName
"Vasya"
*Main> CatHeight `DM.lookup` cbHead t
Nothing
*Main> CatHeight `DM.lookup` cbHead (cbTail t)
Just 5
Поддтипирование можно делать через
data SubCat :: * -> * where
CatSurname :: SubCat String
SubCat :: SubCat (DM.DMap CatProps)
Хотя это и не идеальный вариант.
Но в обычном коде можно следовать KISS и не выпендриваться.