পার্থক্য কি . (ডট) এবং $ (ডলার সাইন)?


709

ডট (.)এবং ডলারের চিহ্নের মধ্যে পার্থক্য কী ($)?

আমি এটি বুঝতে পেরেছি যে, প্রথম বন্ধনী ব্যবহার করার প্রয়োজন নেই বলে তারা উভয় সিনট্যাকটিক চিনি।

উত্তর:


1226

$অপারেটর বন্ধনী এড়ানো জন্য। এটির পরে যা কিছু প্রদর্শিত হবে তার আগে যে কিছু আসে তার চেয়ে বেশি প্রাধান্য পাবে।

উদাহরণস্বরূপ, আসুন আমরা বলি যে আপনার কাছে একটি লাইন রয়েছে যা পড়ে:

putStrLn (show (1 + 1))

আপনি যদি এই বন্ধনীগুলি থেকে মুক্তি পেতে চান তবে নীচের যে কোনও লাইন একই কাজ করবে:

putStrLn (show $ 1 + 1)
putStrLn $ show (1 + 1)
putStrLn $ show $ 1 + 1

.অপারেটরের প্রাথমিক উদ্দেশ্য বন্ধনী এড়ানো নয়, চেইন ফাংশনগুলি। এটি আপনাকে ডানদিকে যা বামদিকে প্রদর্শিত হবে তার ইনপুটটিতে ডানদিকে যা প্রদর্শিত হবে তার আউটপুট টাই করতে দেয়। এটি সাধারণত কম বন্ধনীতেও ফলাফল দেয় তবে ভিন্নভাবে কাজ করে।

একই উদাহরণে ফিরে যাওয়া:

putStrLn (show (1 + 1))
  1. (1 + 1)একটি ইনপুট নেই এবং তাই .অপারেটরের সাথে ব্যবহার করা যাবে না ।
  2. showএকটি নিতে Intএবং ফিরে আসতে পারে String
  3. putStrLnএকটি নিতে Stringএবং একটি ফেরত দিতে পারেন IO ()

আপনি এটি পছন্দ করতে চেইন showকরতে putStrLnপারেন:

(putStrLn . show) (1 + 1)

যদি এটি আপনার পছন্দ অনুসারে অনেক বেশি বন্ধনী হয় তবে $অপারেটরের মাধ্যমে এগুলি থেকে মুক্তি পান :

putStrLn . show $ 1 + 1

54
আসলে, যেহেতু + একটি ফাংশনও তাই আপনি এটি প্রাক উপদ্বীপ তৈরি করতে পারেন না তবে এটি `putStrLn এর মতো করে এটিও রচনা করতে পারেন। দেখান (+) 1 1 it's যে এটি কোনও পরিষ্কার নয়, তবে আমার অর্থ ... আপনি পারতেন, তাই না?
কোডেক্সআর্কানিয়াম

4
@ কোডেক্সআরকানাম এই উদাহরণে, এর মতো কিছু putStrLn . show . (+1) $ 1সমান হবে। আপনি যে সঠিক (সঠিক?) ইনফিক্স অপারেটর ফাংশন হয়।
মাইকেল স্টিল

79
আমি অবাক হই কেন কেন কেউ কখনই এর মতো ব্যবহারের উল্লেখ করে না map ($3)। আমি বলতে চাইছি, আমি বেশিরভাগ ক্ষেত্রে প্রথম $বন্ধনী এড়াতে ব্যবহার করি তবে এটি সেখানে নেই এগুলি।
কিউবিক

43
map ($3)টাইপ একটি ফাংশন Num a => [(a->b)] -> [b]। এটি একটি সংখ্যা গ্রহণ করে ফাংশনগুলির একটি তালিকা নেয়, সেগুলির জন্য 3 টি প্রয়োগ করে ফলাফল সংগ্রহ করে।
কিউবিক

21
অন্যান্য অপারেটরগুলির সাথে ব্যবহার করার সময় আপনাকে সতর্কতা অবলম্বন করতে হবে। "x + f (y + z)" "x + f $ y + z" এর সমান নয় কারণ পরেরটির প্রকৃত অর্থ "(x + f) (y + z)" (অর্থাত x এবং f এর যোগফল) একটি ফাংশন হিসাবে বিবেচিত)।
পল জনসন

186

তাদের বিভিন্ন ধরণের এবং বিভিন্ন সংজ্ঞা রয়েছে:

infixr 9 .
(.) :: (b -> c) -> (a -> b) -> (a -> c)
(f . g) x = f (g x)

infixr 0 $
($) :: (a -> b) -> a -> b
f $ x = f x

($)সাধারণত ক্রিয়াকলাপের অ্যাপ্লিকেশন প্রতিস্থাপনের উদ্দেশ্যে তৈরি করা হয়েছে তবে বন্ধনীগুলি এড়াতে সহায়তা করার জন্য একটি আলাদা অগ্রাধিকারে। (.)একটি নতুন ফাংশন করতে দুটি ফাংশন একসাথে রচনা করার জন্য।

কিছু ক্ষেত্রে এগুলি বিনিময়যোগ্য, তবে এটি সাধারণভাবে সত্য নয়। তারা যেখানে রয়েছে তার উদাহরণ উদাহরণ:

f $ g $ h $ x

==>

f . g . h $ x

$S এর শৃঙ্খলে অন্য কথায় , চূড়ান্ত এক ব্যতীত অন্য সবগুলি প্রতিস্থাপন করতে পারে.


1
যদি xকোন ফাংশন হত? তাহলে কি আপনি .চূড়ান্ত হিসাবে ব্যবহার করতে পারেন ?
সমৃদ্ধি

3
@ রিচিজি যদি আপনি প্রকৃতপক্ষে xএই প্রসঙ্গে আবেদন করছেন তবে হ্যাঁ - তবে "চূড়ান্ত" ব্যতীত অন্য কোনও কিছুর জন্য আবেদন করা হবে x। আপনি যদি আবেদন করছেন না x, তবে এটি xমান হওয়ার চেয়ে আলাদা নয় ।
জিএস -

123

এছাড়াও মনে রাখবেন ($)হয় পরিচয় ফাংশন প্রকারের বিশেষ ফাংশন । পরিচয় ফাংশনটি দেখতে এরকম দেখাচ্ছে:

id :: a -> a
id x = x

যদিও ($)এই মত দেখায়:

($) :: (a -> b) -> (a -> b)
($) = id

নোট করুন যে আমি ইচ্ছাকৃতভাবে টাইপ স্বাক্ষরে অতিরিক্ত প্যারেন্টেসিস যুক্ত করেছি।

ব্যবহারগুলি ($)সাধারণত বন্ধনী যুক্ত করে নির্মূল করা যায় (অপারেটরটি যদি কোনও বিভাগে ব্যবহার না করা হয়)। যেমন: f $ g xহয়ে যায় f (g x)

এর ব্যবহারগুলি (.)প্রতিস্থাপন করা প্রায়শই শক্ত; তাদের সাধারণত একটি ল্যাম্বডা বা স্পষ্ট ফাংশন প্যারামিটারের পরিচিতির প্রয়োজন হয়। উদাহরণ স্বরূপ:

f = g . h

হয়ে

f x = (g . h) x

হয়ে

f x = g (h x)

আশাকরি এটা সাহায্য করবে!


"নোট করুন যে আমি ইচ্ছাকৃতভাবে টাইপ স্বাক্ষরে অতিরিক্ত বন্ধনী যুক্ত করেছি" " আমি বিভ্রান্ত ... তুমি কেন এমন করছ?
মতিন উলহাক

3
@ ম্যাটেন উলহাক ($) এর ধরণটি (ক -> খ) -> এ -> বি, যা (ক -> খ) -> (ক -> খ) এর সমান, তবে অতিরিক্ত বন্ধনীগুলি এখানে কিছু যুক্ত করে নির্মলতা.
রডি

2
ওহ, আমি মনে করি আমি এটিকে দুটি টি আর্গুমেন্টের ফাংশন হিসাবে ভাবছিলাম ... তবে কারিগরি করার কারণে এটি একটি ফাংশনটির সাথে ঠিক সমান that
মতিন উলহাক

78

($) মূল্যায়ন আদেশ নিয়ন্ত্রণে প্রথম বন্ধনী যুক্ত না করে ফাংশনগুলিকে এক সাথে শৃঙ্খলিত করতে দেয়:

Prelude> head (tail "asdf")
's'

Prelude> head $ tail "asdf"
's'

সুরকার অপারেটরটি (.)আর্গুমেন্টগুলি নির্দিষ্ট না করে একটি নতুন ফাংশন তৈরি করে:

Prelude> let second x = head $ tail x
Prelude> second "asdf"
's'

Prelude> let second = head . tail
Prelude> second "asdf"
's'

উপরের উদাহরণটি তর্কযোগ্যভাবে উদাহরণস্বরূপ, তবে রচনাটি ব্যবহারের সুবিধার্থে সত্যই তা দেখায় না। এখানে আরও একটি উপমা রয়েছে:

Prelude> let third x = head $ tail $ tail x
Prelude> map third ["asdf", "qwer", "1234"]
"de3"

আমরা যদি কেবল একবার তৃতীয়টি ব্যবহার করি তবে আমরা ল্যাম্বদা ব্যবহার করে এর নাম এড়াতে পারি:

Prelude> map (\x -> head $ tail $ tail x) ["asdf", "qwer", "1234"]
"de3"

শেষ অবধি, রচনা আমাদের ল্যাম্বদা এড়াতে দেয়:

Prelude> map (head . tail . tail) ["asdf", "qwer", "1234"]
"de3"

3
যদি স্ট্যাকওভারফ্লোতে একটি সমন্বয় ফাংশন থাকে তবে আমি এই উত্তরটির উদাহরণের সাথে পূর্ববর্তী দুটি ব্যাখ্যা সংমিশ্রিত উত্তরটিকে পছন্দ করব।
ক্রিস.কিউ 12'14

59

সংক্ষিপ্ত এবং মিষ্টি সংস্করণ:

  • ($) ফাংশনটিকে ডান হাতের আর্গুমেন্টের মানটিতে তার বাম-হাতের আর্গুমেন্ট বলে।
  • (.) ফাংশনটি রচনা করে যা এটির ডান-হাতের যুক্তি যা ফাংশনে তার বাম-হাতের যুক্তি।

29

এমন একটি অ্যাপ্লিকেশন যা দরকারী এবং খুব শীঘ্র বিবরণটি জানতে একটি সময় নিয়েছিল যাতে আপনি একটি শীঘ্রই শিখেন : যেহেতু:

f $ x = f x

এবং ইনফিক্স অপারেটর সমন্বিত একটি এক্সপ্রেশনটির ডান হাতের বন্ধনী এটিকে উপসর্গের ফাংশনে রূপান্তরিত করে, যার সাথে ($ 3) (4+)অ্যানালগাস লিখতে পারে (++", world") "hello"

কেন কেউ এই কাজ করবে? উদাহরণস্বরূপ ফাংশনগুলির তালিকার জন্য। উভয়:

map (++", world") ["hello","goodbye"]`

এবং:

map ($ 3) [(4+),(3*)]

map (\x -> x ++ ", world") ...বা এর চেয়ে কম হয় map (\f -> f 3) ...। স্পষ্টতই, পরের বৈকল্পগুলি বেশিরভাগ মানুষের কাছে আরও পঠনযোগ্য।


14
বিটিডব্লিউ, আমি $3জায়গা ছাড়াই ব্যবহারের বিরুদ্ধে পরামর্শ দেব । যদি টেম্পলেট হাস্কেল সক্ষম করা থাকে তবে এটি একটি স্প্লাইস হিসাবে পার্স করা হবে, তবে $ 3সর্বদা তার অর্থ যা আপনি বলেছেন means সাধারনত হাস্কেলের মধ্যে সিনট্যাক্সের বিটগুলি "চুরি" করার প্রবণতা রয়েছে বলে মনে হয় যে নির্দিষ্ট অপারেটরদের আশেপাশে ফাঁকা স্থান রয়েছে যা তাদের হিসাবে বিবেচনা করা হয়।
জিএস - মনিকাকে

1
প্রথম বন্ধনীগুলি কীভাবে কাজ করছে তা নির্ধারণ করতে আমাকে কিছুটা সময় নিলেন
কেসবাশ

18

হাস্কেল: .(ডট) এবং $(ডলার সাইন) এর মধ্যে পার্থক্য

ডট (.)এবং ডলারের চিহ্নের মধ্যে পার্থক্য কী ($)? আমি এটি বুঝতে পেরেছি যে, প্রথম বন্ধনী ব্যবহার করার প্রয়োজন নেই বলে তারা উভয় সিনট্যাকটিক চিনি।

এইগুলি হল না ব্যবহার প্রথম বন্ধনী প্রয়োজন না করার জন্য অন্বিত চিনি - তারা ফাংশন, রয়েছে - infixed, এইভাবে আমরা তাদের অপারেটরদের কল করতে পারেন।

রচনা করুন, (.)এবং কখন এটি ব্যবহার করবেন।

(.)এটি রচনা ফাংশন। সুতরাং

result = (f . g) x

একটি ফাংশন যে তার যুক্তি প্রেরণ ফল পাসের বিল্ডিং হিসাবে একই gওপর f

h = \x -> f (g x)
result = h x

(.)আপনি রচনা করতে ইচ্ছুক ফাংশনগুলি পাস করার জন্য যখন আপনার কাছে যুক্তি উপলব্ধ নেই তখন ব্যবহার করুন ।

ডান সহযোগী প্রয়োগ করুন, ($)এবং কখন এটি ব্যবহার করবেন

($)নিম্ন বাঁধাইয়ের নজির সহ একটি ডান-অ্যাসোসিয়েটিভ প্রয়োগ ফাংশন। সুতরাং এটি কেবল প্রথমে ডানদিকে জিনিসগুলি গণনা করে। সুতরাং,

result = f $ g x

প্রক্রিয়াগতভাবে এটির মতোই (যা হাস্কেলকে অলসভাবে মূল্যায়ন করা হয় তাই এটি fপ্রথমে মূল্যায়ন করা শুরু করবে ):

h = f
g_x = g x
result = h g_x

বা আরও সংক্ষিপ্তভাবে:

result = f (g x)

($)ফলাফলটিতে পূর্ববর্তী ফাংশনটি প্রয়োগ করার আগে যখন মূল্যায়ন করার জন্য আপনার সমস্ত ভেরিয়েবল থাকে তখন ব্যবহার করুন ।

আমরা প্রতিটি ফাংশনের উত্স পড়ে এটি দেখতে পারি।

উত্স পড়ুন

এখানে উৎস জন্য (.):

-- | Function composition.
{-# INLINE (.) #-}
-- Make sure it has TWO args only on the left, so that it inlines
-- when applied to two functions, even if there is no final argument
(.)    :: (b -> c) -> (a -> b) -> a -> c
(.) f g = \x -> f (g x)

আর এখানে উৎস জন্য ($):

-- | Application operator.  This operator is redundant, since ordinary
-- application @(f x)@ means the same as @(f '$' x)@. However, '$' has
-- low, right-associative binding precedence, so it sometimes allows
-- parentheses to be omitted; for example:
--
-- >     f $ g $ h x  =  f (g (h x))
--
-- It is also useful in higher-order situations, such as @'map' ('$' 0) xs@,
-- or @'Data.List.zipWith' ('$') fs xs@.
{-# INLINE ($) #-}
($)                     :: (a -> b) -> a -> b
f $ x                   =  f x

উপসংহার

যখন আপনার তত্ক্ষণাত ফাংশনটি মূল্যায়নের প্রয়োজন হবে না তখন রচনাটি ব্যবহার করুন। হতে পারে আপনি সেই ফাংশনটি পাস করতে চান যা রচনা থেকে অন্য ফাংশনে ফলাফল দেয়।

আপনি সম্পূর্ণ মূল্যায়নের জন্য সমস্ত যুক্তি সরবরাহ করার সময় অ্যাপ্লিকেশনটি ব্যবহার করুন।

আমাদের উদাহরণস্বরূপ, এটি করণে শব্দার্থগতভাবে পছন্দ করা হবে

f $ g x

যখন আমাদের x(বা বরং, gএর আর্গুমেন্ট) থাকে এবং করি:

f . g

যখন আমরা না।


12

... অথবা আপনি পাইপলাইন ব্যবহার করে নির্মাণগুলি. এবং নির্মাণগুলি এড়াতে পারেন :$

third xs = xs |> tail |> tail |> head

এর পরে আপনি সহায়ক ফাংশনে যোগ করেছেন:

(|>) x y = y x

2
হ্যাঁ, |> এফ # পাইপলাইন অপারেটর।
ব্যবহারকারী 1721780

6
এখানে খেয়াল করা একটা জিনিষ, যে Haskell, কারো নির্দেশ চলে না $অপারেটর আসলে 'আরও এফ # মত কাজ করে গুলি <|চেয়ে এটা আছে |>, সাধারণত মধ্যে Haskell আপনি ভালো উপরের ফাংশন লিখতে চাই: third xs = head $ tail $ tail $ xsঅথবা সম্ভবত এমনকি মত third = head . tail . tail, এফ এ # -style সিনট্যাক্স ভালো কিছু হবে যা:let third = List.head << List.tail << List.tail
বৈদ্যুতিন কফি

1
হাস্কেলকে এফ # এর মতো দেখানোর জন্য কেন কোনও সহায়ক ফাংশন যুক্ত করবেন? -1
ভাইকিংস্টিভ

9
ফ্লিপ $ইতিমধ্যে উপলব্ধ, এবং এটি বলা হচ্ছে & hackage.haskell.org/package/base-4.8.0.0/docs/...
চাপড়ান

11

যে কোনও বিষয়ে (যে কোনও ফাংশন) সম্পর্কে আরও জানার একটি দুর্দান্ত উপায় হ'ল মনে রাখা যে সবকিছুই একটি ফাংশন! এই সাধারণ মন্ত্রটি সহায়তা করে তবে অপারেটরগুলির মতো নির্দিষ্ট ক্ষেত্রে এটি এই ছোট্ট কৌশলটি মনে রাখতে সহায়তা করে:

:t (.)
(.) :: (b -> c) -> (a -> b) -> a -> c

এবং

:t ($)
($) :: (a -> b) -> a -> b

:tউদারভাবে ব্যবহার করতে কেবল মনে রাখবেন , এবং আপনার অপারেটরগুলিকে মুড়ে দিন ()!


11

আমার বিধিটি সহজ (আমিও শিক্ষানবিশ):

  • .আপনি যদি প্যারামিটারটি পাস করতে চান তবে (ফাংশনটি কল করুন) এবং ব্যবহার করবেন না
  • $এখনও কোনও প্যারামিটার না থাকলে ব্যবহার করবেন না (একটি ফাংশন রচনা করুন)

এটাই

show $ head [1, 2]

কখনো ও নহে:

show . head [1, 2]


0

আমি মনে করি আপনি কোথায় ব্যবহার করবেন .এবং $জিনিসগুলি পরিষ্কার করতে সহায়তা করবেন না তার একটি সংক্ষিপ্ত উদাহরণ ।

double x = x * 2
triple x = x * 3
times6 = double . triple

:i times6
times6 :: Num c => c -> c

নোট যে times6ফাংশন রচনা থেকে তৈরি একটি ফাংশন।


0

অন্য সমস্ত উত্তর বেশ ভাল। তবে কীভাবে জিএইচসি আচরণ করে about সে সম্পর্কে একটি গুরুত্বপূর্ণ ব্যবহারযোগ্যতার বিশদ রয়েছে, যা জিএইচসি টাইপ চেকার উচ্চ পদমর্যাদার / পরিমাণযুক্ত প্রকারের সাথে ইনস্টিটিয়ারিয়নের অনুমতি দেয়। $ idউদাহরণস্বরূপ আপনি যদি ধরণটি দেখেন তবে আপনি দেখতে পাবেন এটি কোনও ফাংশন গ্রহণ করবে যার যুক্তি নিজেই একটি বহুকর্মীয় ফাংশন। এর মতো ছোট ছোট জিনিসগুলিকে সমতুল্য আপসেট অপারেটরের সাথে একই নমনীয়তা দেওয়া হয় না। (এটি আসলে আমাকে অবাক করে দেয় যে $! একই চিকিত্সার প্রাপ্য কিনা)

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.