ডট (.)
এবং ডলারের চিহ্নের মধ্যে পার্থক্য কী ($)
?
আমি এটি বুঝতে পেরেছি যে, প্রথম বন্ধনী ব্যবহার করার প্রয়োজন নেই বলে তারা উভয় সিনট্যাকটিক চিনি।
ডট (.)
এবং ডলারের চিহ্নের মধ্যে পার্থক্য কী ($)
?
আমি এটি বুঝতে পেরেছি যে, প্রথম বন্ধনী ব্যবহার করার প্রয়োজন নেই বলে তারা উভয় সিনট্যাকটিক চিনি।
উত্তর:
$
অপারেটর বন্ধনী এড়ানো জন্য। এটির পরে যা কিছু প্রদর্শিত হবে তার আগে যে কিছু আসে তার চেয়ে বেশি প্রাধান্য পাবে।
উদাহরণস্বরূপ, আসুন আমরা বলি যে আপনার কাছে একটি লাইন রয়েছে যা পড়ে:
putStrLn (show (1 + 1))
আপনি যদি এই বন্ধনীগুলি থেকে মুক্তি পেতে চান তবে নীচের যে কোনও লাইন একই কাজ করবে:
putStrLn (show $ 1 + 1)
putStrLn $ show (1 + 1)
putStrLn $ show $ 1 + 1
.
অপারেটরের প্রাথমিক উদ্দেশ্য বন্ধনী এড়ানো নয়, চেইন ফাংশনগুলি। এটি আপনাকে ডানদিকে যা বামদিকে প্রদর্শিত হবে তার ইনপুটটিতে ডানদিকে যা প্রদর্শিত হবে তার আউটপুট টাই করতে দেয়। এটি সাধারণত কম বন্ধনীতেও ফলাফল দেয় তবে ভিন্নভাবে কাজ করে।
একই উদাহরণে ফিরে যাওয়া:
putStrLn (show (1 + 1))
(1 + 1)
একটি ইনপুট নেই এবং তাই .
অপারেটরের সাথে ব্যবহার করা যাবে না ।show
একটি নিতে Int
এবং ফিরে আসতে পারে String
।putStrLn
একটি নিতে String
এবং একটি ফেরত দিতে পারেন IO ()
।আপনি এটি পছন্দ করতে চেইন show
করতে putStrLn
পারেন:
(putStrLn . show) (1 + 1)
যদি এটি আপনার পছন্দ অনুসারে অনেক বেশি বন্ধনী হয় তবে $
অপারেটরের মাধ্যমে এগুলি থেকে মুক্তি পান :
putStrLn . show $ 1 + 1
putStrLn . show . (+1) $ 1
সমান হবে। আপনি যে সঠিক (সঠিক?) ইনফিক্স অপারেটর ফাংশন হয়।
map ($3)
। আমি বলতে চাইছি, আমি বেশিরভাগ ক্ষেত্রে প্রথম $
বন্ধনী এড়াতে ব্যবহার করি তবে এটি সেখানে নেই এগুলি।
map ($3)
টাইপ একটি ফাংশন Num a => [(a->b)] -> [b]
। এটি একটি সংখ্যা গ্রহণ করে ফাংশনগুলির একটি তালিকা নেয়, সেগুলির জন্য 3 টি প্রয়োগ করে ফলাফল সংগ্রহ করে।
তাদের বিভিন্ন ধরণের এবং বিভিন্ন সংজ্ঞা রয়েছে:
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 এর শৃঙ্খলে অন্য কথায় , চূড়ান্ত এক ব্যতীত অন্য সবগুলি প্রতিস্থাপন করতে পারে.
x
কোন ফাংশন হত? তাহলে কি আপনি .
চূড়ান্ত হিসাবে ব্যবহার করতে পারেন ?
x
এই প্রসঙ্গে আবেদন করছেন তবে হ্যাঁ - তবে "চূড়ান্ত" ব্যতীত অন্য কোনও কিছুর জন্য আবেদন করা হবে x
। আপনি যদি আবেদন করছেন না x
, তবে এটি x
মান হওয়ার চেয়ে আলাদা নয় ।
এছাড়াও মনে রাখবেন ($)
হয় পরিচয় ফাংশন প্রকারের বিশেষ ফাংশন । পরিচয় ফাংশনটি দেখতে এরকম দেখাচ্ছে:
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)
আশাকরি এটা সাহায্য করবে!
($)
মূল্যায়ন আদেশ নিয়ন্ত্রণে প্রথম বন্ধনী যুক্ত না করে ফাংশনগুলিকে এক সাথে শৃঙ্খলিত করতে দেয়:
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"
এমন একটি অ্যাপ্লিকেশন যা দরকারী এবং খুব শীঘ্র বিবরণটি জানতে একটি সময় নিয়েছিল যাতে আপনি একটি শীঘ্রই শিখেন : যেহেতু:
f $ x = f x
এবং ইনফিক্স অপারেটর সমন্বিত একটি এক্সপ্রেশনটির ডান হাতের বন্ধনী এটিকে উপসর্গের ফাংশনে রূপান্তরিত করে, যার সাথে ($ 3) (4+)
অ্যানালগাস লিখতে পারে (++", world") "hello"
।
কেন কেউ এই কাজ করবে? উদাহরণস্বরূপ ফাংশনগুলির তালিকার জন্য। উভয়:
map (++", world") ["hello","goodbye"]`
এবং:
map ($ 3) [(4+),(3*)]
map (\x -> x ++ ", world") ...
বা এর চেয়ে কম হয় map (\f -> f 3) ...
। স্পষ্টতই, পরের বৈকল্পগুলি বেশিরভাগ মানুষের কাছে আরও পঠনযোগ্য।
$3
জায়গা ছাড়াই ব্যবহারের বিরুদ্ধে পরামর্শ দেব । যদি টেম্পলেট হাস্কেল সক্ষম করা থাকে তবে এটি একটি স্প্লাইস হিসাবে পার্স করা হবে, তবে $ 3
সর্বদা তার অর্থ যা আপনি বলেছেন means সাধারনত হাস্কেলের মধ্যে সিনট্যাক্সের বিটগুলি "চুরি" করার প্রবণতা রয়েছে বলে মনে হয় যে নির্দিষ্ট অপারেটরদের আশেপাশে ফাঁকা স্থান রয়েছে যা তাদের হিসাবে বিবেচনা করা হয়।
হাস্কেল:
.
(ডট) এবং$
(ডলার সাইন) এর মধ্যে পার্থক্যডট
(.)
এবং ডলারের চিহ্নের মধ্যে পার্থক্য কী($)
? আমি এটি বুঝতে পেরেছি যে, প্রথম বন্ধনী ব্যবহার করার প্রয়োজন নেই বলে তারা উভয় সিনট্যাকটিক চিনি।
এইগুলি হল না ব্যবহার প্রথম বন্ধনী প্রয়োজন না করার জন্য অন্বিত চিনি - তারা ফাংশন, রয়েছে - 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
যখন আমরা না।
... অথবা আপনি পাইপলাইন ব্যবহার করে নির্মাণগুলি.
এবং নির্মাণগুলি এড়াতে পারেন :$
third xs = xs |> tail |> tail |> head
এর পরে আপনি সহায়ক ফাংশনে যোগ করেছেন:
(|>) x y = y x
$
অপারেটর আসলে 'আরও এফ # মত কাজ করে গুলি <|
চেয়ে এটা আছে |>
, সাধারণত মধ্যে Haskell আপনি ভালো উপরের ফাংশন লিখতে চাই: third xs = head $ tail $ tail $ xs
অথবা সম্ভবত এমনকি মত third = head . tail . tail
, এফ এ # -style সিনট্যাক্স ভালো কিছু হবে যা:let third = List.head << List.tail << List.tail
যে কোনও বিষয়ে (যে কোনও ফাংশন) সম্পর্কে আরও জানার একটি দুর্দান্ত উপায় হ'ল মনে রাখা যে সবকিছুই একটি ফাংশন! এই সাধারণ মন্ত্রটি সহায়তা করে তবে অপারেটরগুলির মতো নির্দিষ্ট ক্ষেত্রে এটি এই ছোট্ট কৌশলটি মনে রাখতে সহায়তা করে:
:t (.)
(.) :: (b -> c) -> (a -> b) -> a -> c
এবং
:t ($)
($) :: (a -> b) -> a -> b
:t
উদারভাবে ব্যবহার করতে কেবল মনে রাখবেন , এবং আপনার অপারেটরগুলিকে মুড়ে দিন ()
!
আমার বিধিটি সহজ (আমিও শিক্ষানবিশ):
.
আপনি যদি প্যারামিটারটি পাস করতে চান তবে (ফাংশনটি কল করুন) এবং ব্যবহার করবেন না$
এখনও কোনও প্যারামিটার না থাকলে ব্যবহার করবেন না (একটি ফাংশন রচনা করুন)এটাই
show $ head [1, 2]
কখনো ও নহে:
show . head [1, 2]
আমি মনে করি আপনি কোথায় ব্যবহার করবেন .
এবং $
জিনিসগুলি পরিষ্কার করতে সহায়তা করবেন না তার একটি সংক্ষিপ্ত উদাহরণ ।
double x = x * 2
triple x = x * 3
times6 = double . triple
:i times6
times6 :: Num c => c -> c
নোট যে times6
ফাংশন রচনা থেকে তৈরি একটি ফাংশন।
অন্য সমস্ত উত্তর বেশ ভাল। তবে কীভাবে জিএইচসি আচরণ করে about সে সম্পর্কে একটি গুরুত্বপূর্ণ ব্যবহারযোগ্যতার বিশদ রয়েছে, যা জিএইচসি টাইপ চেকার উচ্চ পদমর্যাদার / পরিমাণযুক্ত প্রকারের সাথে ইনস্টিটিয়ারিয়নের অনুমতি দেয়। $ id
উদাহরণস্বরূপ আপনি যদি ধরণটি দেখেন তবে আপনি দেখতে পাবেন এটি কোনও ফাংশন গ্রহণ করবে যার যুক্তি নিজেই একটি বহুকর্মীয় ফাংশন। এর মতো ছোট ছোট জিনিসগুলিকে সমতুল্য আপসেট অপারেটরের সাথে একই নমনীয়তা দেওয়া হয় না। (এটি আসলে আমাকে অবাক করে দেয় যে $! একই চিকিত্সার প্রাপ্য কিনা)