हास्केल प्रस्तावना में 'कॉन्स्ट' की क्या बात है?


92

हास्केल प्रस्तावना के माध्यम से देख रहा हूं, मैं एक समारोह देखता हूं const:

const x _ = x

मैं इस फ़ंक्शन के संबंध में कुछ भी प्रासंगिक नहीं जान सकता।

क्या बात है? क्या कोई इस बात का उदाहरण दे सकता है कि इस फ़ंक्शन का उपयोग कहाँ किया जा सकता है?


10
एक उदाहरण: backgroundColor :: Text -> Colorमेरे लिए हैbackgroundColor = const White
जेन

जवाबों:


83

जब आपको उनके सभी लचीलेपन की आवश्यकता नहीं होती है, तो यह उच्च-क्रम के कार्यों के लिए उपयोगी होता है। उदाहरण के लिए, monadic अनुक्रम ऑपरेटर >>को monadic bind ऑपरेटर के रूप में परिभाषित किया जा सकता है

x >> y = x >>= const y

यह एक मेमने का उपयोग करने की तुलना में कुछ हद तक बकवास है

x >> y = x >>= \_ -> y

और आप इसे बिंदु-मुक्त भी उपयोग कर सकते हैं

(>>) = (. const) . (>>=)

हालाँकि मैं इस मामले में विशेष रूप से सलाह नहीं देता।


9
+1। पार्सर कॉम्बिनेटरों का उपयोग करते समय यह भी अक्सर आता है।
फ्रेड फू

47
आह, तो यह एक 'फंक्शन जनरेटर' का अधिक है - मैं इसे एक तर्क के साथ उपयोग करता हूं, और यह मुझे एक फ़ंक्शन (एक तर्क लेते हुए) देता है जो हमेशा एक स्थिर मूल्य देता है। इसलिए में map (const 42) [1..5]परिणाम [42, 42, 42, 42, 42]
14

2
stusmith: आप समझ गए। constएक फ़ंक्शन के लिए एकल तर्क को लागू करने के लिए उपयोगी है जहां एक की आवश्यकता होती है (जैसे कि पास करना map)।
कोनल सेप

8
@stusmith: आप इसे कुछ दिलचस्प तरीकों से इस्तेमाल कर सकते हैं:head = foldr const (error "Prelude.head: empty list")
rampion

27

हमार के उत्कृष्ट प्रत्यक्ष उत्तर को जोड़ने के लिए: विनम्र कार्य जैसे constऔर idवास्तव में उच्च क्रम फ़ंक्शन के रूप में उसी कारण से उपयोगी होते हैं कि वे एसकेआई कॉम्बिनेटर कैलकुलस में मौलिक हैं ।

ऐसा नहीं है कि मुझे लगता है कि हैसेल के प्रस्तावना कार्यों को सचेत रूप से उस औपचारिक प्रणाली या किसी भी चीज के बाद मॉडल किया गया था। यह सिर्फ इतना है कि हैस्केल में समृद्ध अमूर्त बनाना बहुत आसान है, इसलिए आप अक्सर देखते हैं कि इस प्रकार की सैद्धांतिक चीजें व्यावहारिक रूप से उपयोगी होती हैं।

बेशर्म प्लग, लेकिन मैं के बारे में कैसे के लिए अनुप्रयोगी उदाहरण ब्लॉग (->)वास्तव में कर रहे Sहैं और Kcombinators यहाँ , कि अगर कुछ ऐसी बातें आपकी रुचि है।


8
खैर, SKI कॉम्बिनेटरों ने निश्चित रूप से प्रस्तावना को प्रभावित किया। मुझे याद है जो जोस के साथ बहस करना कि क्या एस कॉम्बिनेटर को शामिल किया जाना चाहिए या नहीं।
augustss

4
संयोग से, ((->) e)पाठक मोनाद भी है - Readerऔर जैसे कि सिर्फ newtypeरैपर होने के कारण - और askफ़ंक्शन तब है id, इसलिए यह Iभी है। आप हास्केल करी के मूल BCKW आधार पर बजाय देखें, तो B, Kहै, और Wकर रहे हैं fmap, returnऔर joinक्रमशः।
सीए मैक्कन

1
उत्तर में ब्लॉग लिंक मृत है। : अब यह यहाँ इंगित करना चाहिए brandon.si/code/...
nsxt

22

उपयोग करने के लिए एक सरल उदाहरण constहै Data.Functor.(<$)। इस फ़ंक्शन के साथ आप कह सकते हैं: मेरे पास यहां एक फन्नेकार है जिसमें कुछ उबाऊ है, लेकिन इसके बजाय मैं चाहता हूं कि इसमें दूसरी दिलचस्प बात है, फनकार के आकार को बदले बिना। उदाहरण के लिए

import Data.Functor

42 <$ Just "boring"
--> Just 42

42 <$ Nothing
--> Nothing

"cool" <$ ["nonsense","stupid","uninteresting"]
--> ["cool","cool","cool"]

परिभाषा है:

(<$) :: a -> f b -> f a
(<$) =  fmap . const

या व्यर्थ के रूप में नहीं लिखा:

cool <$ uncool =  fmap (const cool) uncool

आप देखते हैं कि constइनपुट के बारे में "भूलने" के लिए यहां कैसे उपयोग किया जाता है।


21

मैं इस फ़ंक्शन के संबंध में कुछ भी प्रासंगिक नहीं जान सकता।

अन्य जवाबों में से कई अपेक्षाकृत गूढ़ (कम से कम नवागंतुक के) अनुप्रयोगों पर चर्चा करते हैं const। यहाँ एक सरल एक है: आप constएक लैम्ब्डा से छुटकारा पाने के लिए उपयोग कर सकते हैं जो दो तर्क लेता है, पहले एक को दूर फेंकता है लेकिन दूसरे के साथ कुछ दिलचस्प करता है।

उदाहरण के लिए, निम्नलिखित (अक्षम लेकिन शिक्षाप्रद) का कार्यान्वयन length,

length' = foldr (\_ acc -> 1 + acc) 0

के रूप में फिर से लिखा जा सकता है

length' = foldr (const (1+)) 0

जो शायद अधिक सुरुचिपूर्ण है।

अभिव्यक्ति const (1+)वास्तव में शब्दार्थ के बराबर है \_ acc -> 1 + acc, क्योंकि यह एक तर्क लेता है, इसे दूर फेंकता है, और अनुभाग को वापस करता है (1+)


4
मुझे यह समझने में 5 मिनट लगे कि यह कैसे काम करता है :)
मुकेश सोनी

15

एक अन्य उपयोग कक्षा के सदस्य कार्यों को लागू करने के लिए है जिनके पास एक डमी तर्क है जिसका मूल्यांकन नहीं किया जाना चाहिए (अस्पष्ट प्रकारों को हल करने के लिए उपयोग किया जाता है)। उदाहरण जो Data.bits में हो सकता है:

instance Bits Int where
  isSigned = const True
  bitSize  = const wordSize
  ...

कॉन्स्ट का उपयोग करके हम स्पष्ट रूप से कहते हैं कि हम निरंतर मूल्यों को परिभाषित कर रहे हैं।

व्यक्तिगत रूप से मैं डमी मापदंडों के उपयोग को नापसंद करता हूं, लेकिन अगर वे एक कक्षा में उपयोग किए जाते हैं तो यह उदाहरण लिखने का एक अच्छा तरीका है।


प्रॉक्सी तर्क वास्तव में बहुत बेहतर हैं, और हाल ही के जीएचसी को लक्षित करते समय, टाइप एप्लिकेशन बड़े करीने से करते हैं।
19

2

constहो सकता है कि सिर्फ वही कार्यान्वयन हो जो आप अन्य कार्यों के साथ संयोजन के लिए देख रहे हैं। यहाँ एक उदाहरण मैंने खोजा है।

मान लें कि हम 2-टुपल्स की संरचना को 2-टुपल्स की एक और संरचना में फिर से लिखना चाहते हैं। मैं इसे इस प्रकार व्यक्त कर सकता हूं:

((a,b),(c,d))  (a,(c,(5,a)))

मैं पैटर्न मिलान के साथ सीधे-आगे की परिभाषा दे सकता हूं:

f ((a,b),(c,d)) = (a,(c,(5,a)))

क्या होगा अगर मैं इस तरह के पुनर्लेखन के लिए एक व्यर्थ (टैसिट) समाधान चाहता हूं? कुछ सोच और बाद में, जवाब है कि हम किसी भी पुनर्लेखन को व्यक्त कर सकते हैं (&&&), const, (.), fst, snd। ध्यान दें कि (&&&)से है Control.Arrow

इन कार्यों का उपयोग कर उदाहरण का हल है:

(fst.fst &&& (fst.snd &&& (const 5 &&& fst.fst)))

के साथ समानता पर ध्यान दें (a,(c,(5,a)))। अगर हम &&&साथ बदल दें तो क्या होगा ,? तो यह पढ़ता है:

(fst.fst, (fst.snd, (const 5, fst.fst)))

ध्यान दें कि aपहला तत्व का पहला तत्व कैसा है, और यही fst.fstप्रोजेक्ट है। ध्यान दें कि cदूसरे तत्व का पहला तत्व कैसे है, और यही fst.sndप्रोजेक्ट है। यही है, चर अपने स्रोत के लिए मार्ग बन जाते हैं।

constहमें स्थिरांक लगाने की अनुमति देता है। दिलचस्प है कि नाम का अर्थ के साथ क्या मतलब है!

मैं तो अनुप्रयोगी के साथ इस विचार सामान्यीकृत, ताकि आप एक व्यर्थ शैली में किसी भी समारोह में लिख सकते हैं (जब तक कि आप मामले विश्लेषण जैसे काम करता है, के रूप में उपलब्ध है maybe, either, bool)। फिर, constस्थिरांक को शुरू करने की भूमिका निभाता है। आप इस काम को Data.Function.Tacit पैकेज में देख सकते हैं ।

जब आप लक्ष्य पर, और फिर एक कार्यान्वयन की दिशा में काम करना शुरू करते हैं, तो आप उत्तरों से आश्चर्यचकित हो सकते हैं। यह कहना है, किसी भी एक समारोह के रूप में रहस्यमय हो सकता है एक मशीन में किसी भी एक कोग। यदि आप पूरी मशीन को देखने के लिए वापस खींचते हैं, हालांकि, आप उस संदर्भ को समझ सकते हैं जिसमें यह आवश्यक है।


2

कहते हैं कि आप Nothingsएक स्ट्रिंग की लंबाई के बराबर एक सूची बनाना चाहते हैं । के रूप में constअपना पहला तर्क रिटर्न, कोई दूसरा कोई फर्क, आप कर सकते हैं:

listOfNothings :: String -> [Maybe Char]
listOfNothings = (map . const) Nothing

या, अधिक स्पष्ट रूप से:

listOfNothing st = map (const Nothing) st

0

कहते हैं कि आप एक सूची को घुमाना चाहते हैं। हास्केल में ऐसा करने का एक मुहावरेदार तरीका है:

rotate :: Int -> [a] -> [a] rotate _ [] = [] rotate n xs = zipWith const (drop n (cycle xs)) xs

यह फ़ंक्शन फ़ंक्शन के साथ दो सरणियों को ज़िप करता है const, पहला एक अनंत चक्रीय सरणी, दूसरा वह सरणी जिसके साथ आपने शुरुआत की थी।

const सीमा की जाँच के रूप में कार्य करता है, और चक्रीय सरणी को समाप्त करने के लिए मूल सरणी का उपयोग करता है।

देखें: हास्केल में एक सूची घुमाएं


0

मैं इस फ़ंक्शन के संबंध में कुछ भी प्रासंगिक नहीं जान सकता।

मान लीजिए कि आप किसी दिए गए सूची के सभी बाद उत्पन्न करना चाहते हैं।

प्रत्येक सूची तत्व के लिए, दिए गए बिंदु पर आपके पास ट्रू का विकल्प होता है (इसे वर्तमान में शामिल करें) या गलत (शामिल न करें)। यह फिल्टरएम फ़ंक्शन का उपयोग करके किया जा सकता है ।

ऐशे ही:

 λ> import Control.Monad
 λ> :t filterM
 filterM :: Applicative m => (a -> m Bool) -> [a] -> m [a]
 λ> 

उदाहरण के लिए, हम के सभी subsequences चाहते [1..4]

 λ> filterM  (const [True, False])  [1..4]
 [[1,2,3,4],[1,2,3],[1,2,4],[1,2],[1,3,4],[1,3],[1,4],[1],[2,3,4],[2,3],[2,4],[2],[3,4],[3],[4],[]]
 λ> 
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.