2012-12-24 8 views
7

का उपयोग कर विनील रिकॉर्ड प्रकारों के लिए बाइनरी उदाहरण प्राप्त करने का कोई तरीका है, मैं Vinyl package को आजमा रहा हूं, जो फ़ील्ड लेवल पॉलीमोर्फिज्म के साथ रिकॉर्ड संरचनाओं को बनाने और स्वचालित रूप से प्रदान किए गए लेंस के साथ प्रकार के स्तर का उपयोग करता है। इन सुविधाओं के दोनों, अपने प्रोजेक्ट के लिए बहुत आसान हो जाएगा के रूप में पूर्व रिकॉर्ड संरचनाओं कि नाम संघर्ष बिना एक दूसरे के उप-प्रकार के होते हैं के लिए अनुमति देता है, और बाद में नाटकीय रूप से नेस्टेड ढांचे पर अपडेट सरल करता है।क्या डेरिव और टेम्पलेट हास्केल या अन्यथा

समस्या परिणामी संरचनाओं serialising साथ आता है। आम तौर पर मैं Data.DeriveTH का उपयोग पूर्ण रूप से अपने द्विआधारी उदाहरणों प्राप्त करने के लिए, लेकिन यह इन संरचनाओं से निपटने के लिए सक्षम होने के लिए प्रतीत नहीं होता। निम्नलिखित कोड

{-# 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) 

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. 

इस निकाले जाते हैं में कोड के इस टुकड़े से संबंधित होना मॉड्यूल कन्वर्ट लगता है:

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) [] 

अब मैं डॉन ' टी वास्तव में टेम्पलेट हास्केल को कैसे पढ़ा जाए, इसलिए मैं यहां बहुत प्रगति नहीं कर सकता हूं। यह मेरे लिए हुआ है कि मैं एक डेटा प्रकार के बजाय एक प्रकार पर्याय प्राप्त खिला कर रहा हूँ और यह है कि यह तोड़ने जा सकता है, तो मैं एक newtype में यह लपेटकर की कोशिश की:

newtype Entity2 = Entity2 {entity :: Entity} 

$(derive makeBinary ''Entity2) 

जो यह और भी अधिक कुंठित त्रुटि की ओर जाता है:

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 

Convert.hs में देख रहे हैं हम

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 

अब मेरा अनुमान है कि यह है कि क्या गलत हो रहा है कि GHC 7.6 नई भाषा शुरू की है है निर्माण करती है कि निकाले जाते हैं टेम्पलेट Haskell खाते में नहीं ले रहा है, जो गैर-संपूर्ण पैटर्न की ओर अग्रसर है।

तो मेरी सवाल है, वहाँ किसी तरह आगे या तो प्राप्त करने के लिए जोड़ने, या विनाइल रिकॉर्ड प्रकार, या कुछ इसी तरह से अपने ही व्युत्पत्ति लिख कर रहा है? यदि विनील के लाभों को सभी धारावाहिकों को लिखने के हाथों से व्यापार करना पड़ा तो यह शर्म की बात होगी।

+2

यह संभव हो जाना चाहिए हाथ एक बार के लिए उदाहरणों लिखने के लिए सभी विनील रिकॉर्ड, 'शो' उदाहरण कैसे लिखा जाता है। –

+0

मैं मूल रूप से सोचा था कि आप वें के बिना इस तरह यह नहीं कर सका, कम से कम नहीं, लेकिन अब आप यह उल्लेख मैं अच्छी तरह से गलत हो सकता है। मुझे जाना होगा ... –

उत्तर

7

मैं सभी प्रकार प्रवंचना पर जा के साथ Binary उदाहरणों लेखन के साथ कुछ समस्याएं आ जाने की उम्मीद है, लेकिन यह नहीं हो सकता है किसी भी आसान:

instance Binary (Rec '[]) where 
    put RNil = return() 
    get = return RNil 

instance (Binary t, Binary (Rec fs)) => Binary (Rec ((sy ::: t) ': fs)) where 
    put ((_,x) :& xs) = put x >> put xs 
    get = do 
    x <- get 
    xs <- get 
    return ((Field, x) :& xs) 
+3

यह आश्चर्यजनक है, मुझे आपके द्वारा लिया गया समय में लगभग आधे रास्ते मिल गए, धन्यवाद! लगभग हर दिन मैं इस भाषा और उसके समुदाय से प्यार करने के लिए एक नए कारण से मिलता हूं। –

+1

(विनाइल यहाँ निर्माता!) यहां तक ​​कि मैं इसे कैसे आसान था हैरान हूँ। अच्छा काम, @Sjoerd विस्चर! –

संबंधित मुद्दे