Próbowałem od Vinyl package, który wykorzystuje rodzaje rodzajów poziomów do tworzenia struktur rekordów z polimorfizmem na poziomie pola i automatycznie dostarczanymi obiektywami. Obie te funkcje byłyby bardzo przydatne w moim projekcie, ponieważ pierwsza z nich pozwala na tworzenie rekordowych struktur, które są pod-typami bez konfliktów nazw, a ta ostatnia znacznie upraszcza aktualizacje zagnieżdżonych struktur.Czy istnieje sposób na wyprowadzenie wystąpień binarnych dla typów rekordów winylowych przy użyciu wyliczeń i szablonów Haskell lub w inny sposób
Problem polega na szeregowaniu uzyskanych struktur. Zwykle używam Data.DeriveTH do automatycznego generowania instancji binarnych, ale wydaje się, że nie poradzę sobie z tymi strukturami. Poniższy kod
{-# LANGUAGE DataKinds, TypeOperators #-}
{-# LANGUAGE FlexibleContexts, NoMonomorphismRestriction #-}
{-# LANGUAGE TypeSynonymInstances, FlexibleInstances #-}
{-# LANGUAGE TemplateHaskell #-}
import Data.Vinyl
import Data.Binary
import Data.DeriveTH
eID = Field :: "eID" ::: Int
location = Field :: "location" ::: (Double, Double)
type Entity = Rec
[ "eID" ::: Int
, "location" ::: (Double, Double)
]
$(derive makeBinary ''Entity)
skutkuje tym błędem w GHCI
Exception when trying to run compile-time code:
Could not convert Dec to Decl
TySynD Main.Entity [] (AppT (ConT Data.Vinyl.Rec.Rec) (AppT (AppT PromotedConsT (AppT (AppT (ConT Data.Vinyl.Field.:::) (LitT (StrTyLit "eID"))) (ConT GHC.Types.Int))) (AppT (AppT PromotedConsT (AppT (AppT (ConT Data.Vinyl.Field.:::) (LitT (StrTyLit "location"))) (AppT (AppT (TupleT 2) (ConT GHC.Types.Double)) (ConT GHC.Types.Double)))) PromotedNilT)))
Language/Haskell/Convert.hs:(37,14)-(40,8): Non-exhaustive patterns in case
Code: derive makeBinary ''Entity
Failed, modules loaded: none.
To wydaje się być związane z tego kawałka kodu w dryfu Konwersja moduł:
instance Convert TH.Dec HS.Decl where
conv x = case x of
DataD cxt n vs con ds -> f DataType cxt n vs con ds
NewtypeD cxt n vs con ds -> f NewType cxt n vs [con] ds
where
f t cxt n vs con ds = DataDecl sl t (c cxt) (c n) (c vs) (c con) []
Teraz don” t naprawdę wiesz, jak czytać szablon Haskell, więc nie mogę zrobić tutaj dużego postępu. Przyszło mi do głowy, że ja karmię czerpać typu synonim zamiast typu danych i że może być złamanie go, więc próbowałem owijając go w newtype:
newtype Entity2 = Entity2 {entity :: Entity}
$(derive makeBinary ''Entity2)
co prowadzi do tego jeszcze bardziej rozwarty błędu:
Exception when trying to run compile-time code:
Could not convert Type to Type
AppT (AppT PromotedConsT (AppT (AppT (ConT Data.Vinyl.Field.:::) (LitT (StrTyLit "eID"))) (ConT GHC.Types.Int))) (AppT (AppT PromotedConsT (AppT (AppT (ConT Data.Vinyl.Field.:::) (LitT (StrTyLit "location"))) (AppT (AppT (TupleT 2) (ConT GHC.Types.Double)) (ConT GHC.Types.Double)))) PromotedNilT)
Could not convert Type to Type
AppT PromotedConsT (AppT (AppT (ConT Data.Vinyl.Field.:::) (LitT (StrTyLit "eID"))) (ConT GHC.Types.Int))
Could not convert Type to Type
PromotedConsT
Language/Haskell/Convert.hs:(71,5)-(80,26): Non-exhaustive patterns in function conv
Patrząc w Convert.hs mamy
instance Convert TH.Type HS.Type where
conv (ForallT xs cxt t) = TyForall (Just $ c xs) (c cxt) (c t)
conv (VarT x) = TyVar $ c x
conv (ConT x) | ',' `elem` show x = TyTuple Boxed []
| otherwise = TyCon $ c x
conv (AppT (AppT ArrowT x) y) = TyFun (c x) (c y)
conv (AppT ListT x) = TyList $ c x
conv (TupleT _) = TyTuple Boxed []
conv (AppT x y) = case c x of
TyTuple b xs -> TyTuple b $ xs ++ [c y]
x -> TyApp x $ c y
teraz Zgaduję, że to, co jest nie tak, że GHC 7.6 wprowadzono nowy język konstruuje że szablon Derive Haskell nie bierze pod uwagę, prowadząc do niewyczerpujących wzorców.
Moje pytanie brzmi, czy istnieje jakiś sposób na to, czy dodać do Derive, czy napisać własne pochodzenie z typów płyt winylowych, czy coś podobnego? Szkoda byłoby, gdyby korzyści płynące z winyla wymknęły się spod ręki, pisząc całą serializację.
powinna istnieć możliwość przekazania napisać instancje raz wszystkie zapisy winylowe, podobne do tego, w jaki sposób napisano instancję 'Show'. –
Początkowo myślałem, że nie możesz tego zrobić, przynajmniej nie bez TH, ale teraz wspomniałeś, że mogę się mylić. Będę musiał ... –