2010-11-30 16 views
6

में गणना के लिए इकाइयों को संरक्षित करना मैं सोच रहा था कि क्या कोई मीठी भाषाएं हैं जो "फीट" बनाम "इंच" या "सेमी" आदि के लिए कुछ प्रकार की अमूर्तता प्रदान करती हैं। मैं जावा में निम्नलिखित की तरह कुछ करने पर विचार कर रहा था:प्रोग्रामिंग

u(56).feet() + u(26).inches() 

और परिणाम के रूप में

17,7292 मीटर की तरह कुछ प्राप्त कर सकेंगे।

एक नया मूल्य बनाते समय एक संभावित दृष्टिकोण है, इसे तुरंत "आधार" इकाई में बदल दें, जैसे मीटर या कुछ, ताकि आप उन्हें आसानी से जोड़ सकें।

हालांकि, मैं बहुत बल्कि, इकाइयों की रक्षा करने की क्षमता है, ताकि कुछ की तरह

u(799.95555).feet() - u(76).feet() 

रिटर्न

723.95555 feet 

और नहीं

243.826452 meters - 23.1648 meters = 220.661652 meters 

//220.661652 meters to feet returns 723.955551 feet 

इस समस्या की तरह लगता है के बाद से यह वास्तव में आम होगा, क्या कोई ढांचा या यहां तक ​​कि एक प्रोग्रामिंग भाषा है जो हैंडल मौजूद है यह सुंदरता से?

मैं के रूप में वे मेरी तरीकों में हैं मैं सिर्फ इकाइयों में जोड़ सकते हैं लगता है, मिलान इकाइयों को एक साथ जोड़ने और केवल +-*/ [जोड़ें/घटाना/गुणा/विभाजन] जब वे अनुरोध कर रहे हैं, जो जोड़ने के लिए अच्छा है और करने के क्रम में परिवर्तित करने के घटाने:

//A 
{ 
    this.inches = 36.2; 
    this.meters = 1; 
} 

//total length is 1.91948 m 

अगर मैं मान

//B 
{ 
    this.inches = 0.8; 
    this.meters = 2; 
} 

//total length is 2.02032 m 

के साथ एक वस्तु बी को यह जोड़ सकते हैं और मैं एक नया उद्देश्य यह है कि है

मिल 10

जो पूरी तरह से भयानक है, जब भी मुझे कोई समस्या नहीं है, मैं इसे परिवर्तित कर सकता हूं। लेकिन इस तरह के गुणा विफल हो जाएगा के रूप में संचालन ...

//A * B = 3.87796383 m^2 
{ 
    this.inches = 28.96; 
    this.meters = 2; 
} 

// ...but multiplying piece-wise and then adding 
// gives you 2.01868383 m^2, assuming you make 2m*1m give you 2 m^2. 

तो सब मैं वास्तव में है कि उदाहरण के साथ दिखाने के लिए चाहते थे कि

(A1 + A2) * (Z1 + Z2) is not (A1 * Z1) + (A2 * Z2) 

और मैं यकीन है कि इसका मतलब यह एक एक में बदलने के लिए है हूँ सामान्य इकाई अगर वे गुणा करना या विभाजित करना चाहते हैं।

उदाहरण कर्मकर्त्ता जवाब हतोत्साहित करने के लिए ज्यादातर था, जिसे आप जोड़ना या उन्हें टुकड़ा के लिहाज से अंतिम क्षण में परिवर्तित करने, के बाद से * और / असफल हो जायेगी पहले घटाना।

tl; dr: क्या प्रोग्रामिंग में इकाइयों को संरक्षित करने के लिए कोई चालाक तरीका हैं? विधियों/दिनचर्याओं का नाम देने के लिए चालाक तरीके हैं जैसे कि मेरे लिए यह समझना आसान है कि मैं क्या जोड़ रहा हूं और घटा रहा हूं, आदि?

उत्तर

5

मुझे पता है कि ऐसी भाषा है, हालांकि मैंने इसे स्वयं नहीं उपयोग किया है।
इसे Frink कहा जाता है।

यह न केवल आपको एक ही आयाम के लिए विभिन्न इकाइयों को मिश्रण करने की अनुमति देता है बल्कि कई अलग-अलग भौतिक मापों पर भी काम करता है। sample calculations अपनी साइट पर एक मजेदार पढ़ा है। मुझे विशेष रूप से Superman बिट पसंद है।

+1

फ़्रिंक अद्भुत है। इसे आसानी से जावा से भी उपयोग किया जा सकता है। इसके अलावा, किसी भी भाषा डिजाइनर जो 30 मिनट के फार्ट मजाक में गंभीर सम्मेलन में एक वार्तालाप करने का प्रबंधन करता है, कुछ मुफ्त स्टैक ओवरफ्लो पीआर का हकदार है! –

0

मैं इकाइयों के साथ बहुत काम किया है और वहाँ कुछ भी व्यापक नहीं है। आप बहुत सारी आंशिक उपयोगिताएं पा सकते हैं (मुझे लगता है कि कुछ यूनिक्स के साथ वितरित किए गए हैं)। एनआईएसटी एक यूनिट मार्कअप भाषा विकसित कर रहा था लेकिन कम से कम एक दशक खाना पकाने वाला रहा है।

ऐसा करने के लिए इसे एक ऑटोलॉजी की आवश्यकता होती है जिसमें इकाइयों को परिभाषित किया जाता है और रूपांतरण के नियम होते हैं। आपको उपसर्गों से निपटना होगा।

यदि आप भौतिक विज्ञान (एसआई इकाइयों) के साथ चिपकते हैं तो 7 (संभवतः 8) आधार इकाई-प्रकार और 22 नामित मात्राएं हैं। लेकिन उन तरीकों की भी एक संख्या है जो उन्हें संयुक्त किया जा सकता है। उदाहरण के लिए त्वरण में परिवर्तन की दर को कुछ लोगों द्वारा "झटका" कहा जाता है। सिद्धांत रूप में आप अनिश्चित अनंत व्युत्पन्न हो सकते हैं।

मुद्राएं इकाइयां हैं? आदि ...

+0

जो अविश्वसनीय रूप से दुर्भाग्यपूर्ण है कि कुछ भी मीठा नहीं है (अभी तक) = ( – sova

+0

जिज्ञासा से बाहर, आपकी राय में फ़्रिंक से क्या गुम है? –

2

कई कार्यात्मक भाषाओं इकाई संरक्षण की इस तरह के लिए प्रकार के निर्माण की अनुमति देते हैं।

-- you need GeneralizedNewtypeDeriving to derive Num 
newtype Feet = Feet {unFeet :: Float} deriving (Eq, Show, Num) 
newtype Meters = Meters {unMeters :: Float} deriving (Eq, Show, Num) 

अब प्रत्येक इकाई अपने स्वयं के प्रकार है, और आप केवल एक ही प्रकार के मूल्यों पर कार्रवाई कर सकता है::

*Main> let a1 = 1 :: Feet 
*Main> let a2 = 2 :: Feet 
*Main> let a3 = 3 :: Meters 
*Main> a1+a2 
Feet 3.0 
*Main> a1+a3 

<interactive>:1:3: 
    Couldn't match expected type `Feet' against inferred type `Meters' 
    In the second argument of `(+)', namely `a3' 
    In the expression: a1 + a3 
    In the definition of `it': it = a1 + a3 
*Main> 

अब आप एक रूपांतरण प्रकार वर्ग के लिए कन्वर्ट करने के लिए बना सकते हैं और हास्केल में किसी भी माप प्रकार से

class LengthMeasure unit where 
    untype :: unit -> Float 
    toFeet :: unit -> Feet 
    toFeet = Feet . (* 3.2808) . untype . toMeters 
    toMeters :: unit -> Meters 
    toMeters = Meters . (* 0.3048) . untype . toFeet 

instance LengthMeasure Feet where 
    untype = unFeet 
    toFeet = id 

instance LengthMeasure Meters where 
    untype = unMeters 
    toMeters = id 

अब हम स्वतंत्र रूप से प्रकार के बीच में बदल सकते हैं:

*Main> a1+toFeet a3 
Feet {unFeet = 10.842401} 

बेशक, इस प्रकार की चीजें करने के लिए पैकेज available हैस्केल में हैं।

चूंकि आप जावा का उपयोग कर रहे हैं, शायद स्कैला या क्लोजर समान क्षमताओं की पेशकश करेगा?

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