Можно ли сделать гетерогенный Data.Map
в Haskell с GADT
вместо Dynamic
? Я попытался смоделировать разнородную коллекцию, как описано в этом ответе:
{-# LANGUAGE GADTs #-}
class Contract a where
toString :: a -> String
data Encapsulated where
Encapsulate :: Contract a => a -> Encapsulated
getTypedObject :: Encapsulated -> a
getTypedObject (Encapsulate x) = x
Идея заключалась в том, что Encapsulated
можно было бы использовать для хранения различных объектов TypeClass a
, а затем извлекать во время выполнения для определенного типа.
Я получаю сообщение об ошибке о том, что тип x
не соответствует Contract a
. Возможно, мне нужно указать какие-то ограничения класса, чтобы сообщить GHC
, что тип x
в Encapsulate x
такой же, как a
в Contract a
?
T.hs:10:34:
Couldn't match expected type ‘a’ with actual type ‘a1’
‘a1’ is a rigid type variable bound by
a pattern with constructor
Encapsulate :: forall a. Contract a => a -> Encapsulated,
in an equation for ‘getTypedObject’
at T.hs:10:17
‘a’ is a rigid type variable bound by
the type signature for getTypedObject :: Encapsulated -> a
at T.hs:9:19
Relevant bindings include
x :: a1 (bound at T.hs:10:29)
getTypedObject :: Encapsulated -> a (bound at T.hs:10:1)
In the expression: x
In an equation for ‘getTypedObject’:
getTypedObject (Encapsulate x) = x
Я пробую этот подход, потому что у меня есть объекты JSON разных типов, и в зависимости от типа, который декодируется во время выполнения по сети, мы хотим получить соответствующий специфичный для типа builder
из Map
(загруженный во время выполнения ввода-вывода в main
из конфигурационных файлов и передается в функцию) и передавать ей декодированные данные JSON того же типа.
Здесь подойдет библиотека Dynamic
. Однако мне интересно узнать, существуют ли другие возможные подходы, такие как GADTs
или datafamilies
.
ExistentialQuantification
, чтобы написать что-то вродеdata Encapsulated = forall a. Show a => Encapsulate a
- person Bartek Banachewicz   schedule 01.04.2016Dynamic
является концептуальным излишеством, а ограниченияTypeable
достаточно.data Box where Box :: Typeable a => a -> Box
. Затем вы можете использовать функции отData.Typeable
доMaybe
, чтобы получить значение из коробки. - person dfeuer   schedule 02.04.2016Typeable
станет значительно более мощным, чем функциональность, предлагаемая в настоящее времяDynamic
. - person dfeuer   schedule 02.04.2016