शुभ दिन हर कोई।अंतिम टैगलेस दृष्टिकोण में डीएसएल शब्द को फिर से परिभाषित करने के लिए कैसे?
हमारा एप्लिकेशन कुछ व्यावसायिक तर्क का वर्णन करने के लिए टाइप किए गए डीएसएल का उपयोग करता है। डीएसएल कई टैगलेस दुभाषियों के साथ आता है।
यहाँ कैसे अपनी शर्तों की घोषणा की जाती है:
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE EmptyDataDecls #-}
class Ctl impl where
-- Lift constants.
cnst :: Show t => t -> impl t
-- Obtain the state.
state :: impl (Maybe Int)
-- Test for equality.
eq :: impl Int -> impl Int -> impl Bool
-- If-then-else.
ite :: impl Bool -> impl t -> impl t -> impl t
-- Processing outcomes.
retry :: impl Outcome
finish :: impl Outcome
-- Require a value.
req :: impl (Maybe t) -> impl t
व्यापार तर्क तो यह डीएसएल में कोड का हिस्सा का उपयोग कर वर्णित है:
proc1 :: Ctl impl => impl Outcome
proc1 = ite (req state `eq` cnst 5) finish retry
इन उच्च स्तरीय परिभाषाओं दुभाषिए के साथ उपयोग करने के लिए रखा जाता है। मैं कैसे व्यवसाय प्रक्रियाओं परिभाषित कर रहे हैं की एक पठनीय शाब्दिक वर्णन प्राप्त करने के लिए एक पाठ दुभाषिया है:
λ> (evalText proc1) :: String
"If (My current state)* equals 5, then Finish, else Retry processing"
इस तरह के विवरण के लिए एक संदर्भ के रूप में इस्तेमाल किया जाता है:
newtype TextE t = TextE { evalText :: String }
instance Ctl TextE where
cnst v = TextE $ show v
state = TextE "My current state"
eq v1 v2 = TextE $ concat [evalText v1, " equals ", evalText v2]
ite cond t e =
TextE $
concat ["If ", evalText cond, ", then ", evalText t, ", else ", evalText e]
retry = TextE "Retry processing"
finish = TextE "Finish"
req v = TextE $ concat ["(", evalText v, ")*"]
texte साथ डीएसएल व्याख्या एक स्ट्रिंग का उत्पादन उपयोगकर्ताओं/विश्लेषकों के लिए।
newtype HaskellE t = HaskellE { evalHaskell :: HaskellType t }
-- Interface between types of DSL and Haskell.
type family HaskellType t
instance Ctl HaskellE where
cnst v = HaskellE v
state = HaskellE dummyState
eq v1 v2 = HaskellE $ evalHaskell v1 == evalHaskell v2
ite cond t e =
HaskellE $
if (evalHaskell cond)
then (evalHaskell t)
else (evalHaskell e)
retry = HaskellE $ print "Retrying..."
finish = HaskellE $ print "Done!"
req [email protected](HaskellE v) =
case v of
Just v' -> HaskellE v'
Nothing ->
HaskellE (error $
"Could not obtain required value from ") -- ++ evalText term)
-- Dummy implementations so that this post may be evaluated
dummyState = Just 5
type Outcome = IO()
type instance HaskellType t = t
यह दुभाषिया का उत्पादन runnable हास्केल कोड:
मैं भी मेटा-भाषा एक और दुभाषिया के साथ (हास्केल) है, जो कैसे आवेदन वास्तव में नियमों का पालन करती है करने के लिए एक डीएसएल अवधि मूल्यांकन कर सकते हैं
λ> (evalHaskell proc1) :: IO()
"Done!"
मेरी समस्या के लिए अब: मैं HaskellE दुभाषिया से texte दुभाषिया उपयोग करना चाहते हैं। उदाहरण के लिए, मैं req
की विफल शाखा को परिभाषित करना चाहता हूं जिसमें त्रुटि संदेश में नेस्टेड शब्द (आमतौर पर evalText term
द्वारा प्राप्त) का टेक्स्ट प्रतिनिधित्व शामिल है। उपरोक्त HaskellE के लिए req
कार्यान्वयन में प्रासंगिक कोड पर टिप्पणी की गई है। टिप्पणी को वापस लाया गया है, तो कोड की तरह
HaskellE (error $
"Could not obtain required value from " ++ evalText term)
लग रहा है हालांकि, प्रकार प्रणाली मुझे ऐसा करने से रोकता है:
tagless.lhs:90:71: Couldn't match expected type ‘TextE t0’ …
with actual type ‘HaskellE (Maybe t)’
Relevant bindings include
v :: HaskellType (Maybe t)
(bound at /home/dzhus/projects/hs-archive/tagless.lhs:85:22)
term :: HaskellE (Maybe t)
(bound at /home/dzhus/projects/hs-archive/tagless.lhs:85:7)
req :: HaskellE (Maybe t) -> HaskellE t
(bound at /home/dzhus/projects/hs-archive/tagless.lhs:85:3)
In the first argument of ‘evalText’, namely ‘term’
In the second argument of ‘(++)’, namely ‘evalText term’
Compilation failed.
संदेश मूल रूप से कहा गया है कि दुभाषिया HaskellE पहले से ही चुना गया है जब प्रकार परिवर्तनीय impl
तत्काल था, और मैं अंदर HaskellE से TextE दुभाषिया का उपयोग नहीं कर सकता।
मैं अपने सिर को चारों ओर क्यों नहीं प्राप्त कर सकता हूं: मैं शब्द को हास्केल से टेक्स्टई में दोबारा कैसे दोहरा सकता हूं?
अगर मैं यहाँ पूरी तरह से गलत हूँ, मैं अपने दृष्टिकोण नयी आकृति प्रदान करना ताकि मैं वास्तव में यह HaskellE अंदर फिर से लागू करने के बिना हास्केल एक से पाठ दुभाषिया का उपयोग कर सकते हैं? ऐसा लगता है कि यह अंतिम संभव के बजाय प्रारंभिक दृष्टिकोण के साथ काफी व्यवहार्य है।
मैंने अपने वास्तविक डीएसएल को तोड़ दिया है और संक्षेप के लिए को सरलीकृत किया है।
(क्या है "का उत्पादन बर्ताव करता है टैगलेस "संदर्भ में?) – user2864740
@ user2864740 यह पेपर बताता है कि इसका क्या अर्थ है; यह चर्चा करता है कि अनुभाग 3.1 में कौन से टैग हैं: http://okmij.org/ftp/tagless-final/course/lecture.pdf –
@DavidYoung धन्यवाद! – user2864740