Tôi đã thử sử dụng loại Vinyl package, sử dụng loại mức loại để tạo cấu trúc bản ghi với đa hình cấp trường và ống kính được cung cấp tự động. Cả hai tính năng này sẽ rất tiện dụng cho dự án của tôi, vì trước đây cho phép các cấu trúc ghi lại là các kiểu con của nhau mà không có xung đột tên, và sau này đơn giản hóa các cập nhật trên các cấu trúc lồng nhau một cách đáng kể.Có cách nào để phát sinh các trường hợp nhị phân cho các loại bản ghi Vinyl sử dụng Derive và Template Haskell hay không
Sự cố xảy ra với việc nối tiếp cấu trúc kết quả. Thông thường tôi sử dụng Data.DeriveTH để tự động lấy được các thể hiện nhị phân, nhưng nó dường như không thể đối phó với các cấu trúc này. Các mã sau
{-# 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)
kết quả trong lỗi này trong 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.
này dường như có liên quan đến đoạn mã này trong lấy được Chuyển đổi mô-đun:
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) []
Bây giờ tôi don' Tôi thực sự biết cách đọc Mẫu Haskell vì vậy tôi không thể thực hiện nhiều tiến bộ ở đây. Nó xảy ra với tôi rằng tôi đang ăn lấy được một loại từ đồng nghĩa chứ không phải là một kiểu dữ liệu và có thể được phá vỡ nó, vì vậy tôi cố gắng gói nó trong một Newtype:
newtype Entity2 = Entity2 {entity :: Entity}
$(derive makeBinary ''Entity2)
dẫn đến lỗi ngay cả tù hơn này:
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
Nhìn trong Convert.hs chúng tôi có
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
Bây giờ tôi đoán rằng những gì đang xảy ra sai là GHC 7,6 đã giới thiệu ngôn ngữ mới xây dựng rằng mẫu lấy Haskell không tính đến, dẫn đến các mẫu không đầy đủ.
Vì vậy, câu hỏi của tôi là, có cách nào đó chuyển tiếp bằng cách thêm vào Derive, hoặc viết nguồn gốc của riêng tôi từ các loại bản ghi Vinyl, hoặc một cái gì đó tương tự? Nó sẽ là một sự xấu hổ nếu những lợi ích của Vinyl đã được giao dịch chống lại tay viết tất cả các serialization.
Nó phải có khả năng viết tay các trường hợp một lần cho tất cả các bản ghi Vinyl, tương tự như cách thể hiện của 'Show' được viết. –
Ban đầu tôi nghĩ rằng bạn không thể làm điều đó như thế, ít nhất là không có TH, nhưng bây giờ bạn đề cập đến nó tôi cũng có thể sai. Tôi sẽ có một chuyến đi ... –