তরকারির সুবিধা কী?


154

আমি কেবল তরকারি সম্পর্কে শিখেছি, এবং আমি ধারণাটি বুঝতে পেরেছিলাম, এটি ব্যবহারে আমি কোনও বড় সুবিধা দেখছি না।

তুচ্ছ উদাহরণ হিসাবে আমি একটি ফাংশন ব্যবহার করি যা দুটি মান যুক্ত করে (এমএল লিখিত)। কারি না করে সংস্করণটি হবে

fun add(x, y) = x + y

এবং হিসাবে বলা হবে

add(3, 5)

তরকারী সংস্করণ হয়

fun add x y = x + y 
(* short for val add = fn x => fn y=> x + y *)

এবং হিসাবে বলা হবে

add 3 5

আমার কাছে মনে হয় এটি কেবল সিনট্যাকটিক চিনি যা ফাংশনটি সংজ্ঞায়িত ও কল করা থেকে এক সেট বন্ধনী সরিয়ে দেয়। আমি কার্যকরী ভাষার অন্যতম গুরুত্বপূর্ণ বৈশিষ্ট্য হিসাবে তালিকাবদ্ধ কারিঙ দেখেছি এবং এই মুহুর্তে আমি এতে কিছুটা আচ্ছন্ন হয়ে পড়েছি। ফাংশনগুলির একটি শৃঙ্খলা তৈরির ধারণা যা প্রতিটি একক প্যারামিটার গ্রহণ করে, একটি ফাংশন পরিবর্তে একটি টুপল লাগে সিনট্যাক্সের একটি সাধারণ পরিবর্তনের জন্য ব্যবহার করা জটিল বলে মনে হয়।

সামান্য সরল বাক্য গঠনটি কি কারিঙের একমাত্র প্রেরণা, বা আমার খুব সাধারণ উদাহরণে সুস্পষ্ট নয় এমন কিছু অন্যান্য সুবিধাও আমি মিস করছি? কারিটিং করা কি কেবল সিনট্যাকটিক চিনির জন্য?


54
একা কারি করানো মূলত অকেজো, তবে ডিফল্টরূপে সমস্ত কার্য সম্পাদন করানো অন্যান্য বৈশিষ্ট্যগুলি ব্যবহারের জন্য আরও সুন্দর করে তোলে। আপনি প্রকৃতপক্ষে কিছু সময়ের জন্য কার্যকরী ভাষা ব্যবহার না করা পর্যন্ত এটির প্রশংসা করা শক্ত।
সিএ ম্যাকক্যান

4
জোয়েলথের্টনের উত্তরের মন্তব্যে ডেলানান দিয়ে যাওয়ার সময় যে কথাটি উল্লেখ করা হয়েছিল, তবে আমি ভেবেছিলাম যে আমি স্পষ্টভাবে উল্লেখ করব, তা হ'ল (কমপক্ষে হাস্কেলের মধ্যে) আপনি আংশিকভাবে কেবলমাত্র ফাংশনগুলিই প্রয়োগ করতে পারবেন না তবে টাইপ কনস্ট্রাক্টরদের সাথেও প্রয়োগ করতে পারেন - এটি যথেষ্ট হতে পারে কুশলী; এটি ভাবতে কিছু হতে পারে।
পল

সবাই হাস্কেলের উদাহরণ দিয়েছে। কারও কারও কাছে অবাক হতে পারে যে কার্চিং কেবল হাস্কেলের ক্ষেত্রেই কার্যকর।
মনোজ আর

@ মনোজআর সকলেই হাসকেলে উদাহরণ দেয় নি
পিএইচডাব্লুডি

1
প্রশ্নে একটি মোটামুটি মজার আলোচনা উত্পন্ন ক্রেতা
ইয়ানিস

উত্তর:


126

কারিড ফাংশনগুলির সাহায্যে আপনি আরও বিমূর্ত ফাংশনগুলির সহজ পুনরায় ব্যবহার করতে পারেন, যেহেতু আপনি বিশেষীকরণ পেতে পারেন। ধরা যাক আপনার একটি যুক্ত ফাংশন রয়েছে

add x y = x + y

এবং আপনি তালিকার প্রতিটি সদস্যের সাথে 2 যোগ করতে চান। হাসকেলে আপনি এটি করবেন:

map (add 2) [1, 2, 3] -- gives [3, 4, 5]
-- actually one could just do: map (2+) [1, 2, 3], but that may be Haskell specific

এখানে সিনট্যাক্স হালকা হয় যদি আপনার কোনও ফাংশন তৈরি করতে হয় add2

add2 y = add 2 y
map add2 [1, 2, 3]

বা যদি আপনাকে কোনও বেনাম ল্যাম্বদা ফাংশন করতে হয়:

map (\y -> 2 + y) [1, 2, 3]

এটি আপনাকে বিভিন্ন বাস্তবায়ন থেকে দূরে বিমূর্ত করার অনুমতি দেয়। ধরা যাক আপনার দুটি দেখার জন্য ফাংশন ছিল। কী / মান জোড়ার তালিকার একটি এবং একটি মানের একটি কী এবং অন্যটি মান থেকে কী থেকে মানগুলির এবং একটি মানের কী থেকে:

lookup1 :: [(Key, Value)] -> Key -> Value -- or perhaps it should be Maybe Value
lookup2 :: Map Key Value -> Key -> Value

তারপরে আপনি এমন একটি ফাংশন তৈরি করতে পারেন যা কী থেকে মান পর্যন্ত কোনও লুকিং ফাংশনকে গ্রহণ করেছে। আপনি এটি উপরের কোনও লুকিং ফাংশনটি পাস করতে পারেন, একটি তালিকা বা মানচিত্রের সাথে যথাক্রমে আংশিকভাবে প্রয়োগ:

myFunc :: (Key -> Value) -> .....

উপসংহার ইন: সংবাহন, ভাল, কারণ এটা আপনি বিশেষজ্ঞ / আংশিকভাবে একটি হালকা সিনট্যাক্স ব্যবহার ফাংশন প্রয়োগ এবং তারপর যেমন উচ্চতর ক্রম ফাংশন প্রায় এই আংশিকভাবে প্রয়োগ ফাংশন পাস করতে দেয় mapবা filter। উচ্চতর অর্ডার ফাংশন (যা প্যারামিটার হিসাবে ফাংশন নেয় বা ফল হিসাবে তাদের ফল দেয়) হ'ল ক্রিয়ামূলক প্রোগ্রামিংয়ের রুটি এবং মাখন, এবং কার্বিং এবং আংশিক প্রয়োগিত ফাংশনগুলি উচ্চতর অর্ডার ক্রিয়াকে আরও কার্যকর এবং সংক্ষিপ্তভাবে ব্যবহার করতে সক্ষম করে।


31
এটি লক্ষণীয় যে, এর কারণে, হাস্কেলের ফাংশনগুলির জন্য ব্যবহৃত যুক্তি আদেশটি প্রায়শই আংশিক প্রয়োগের সম্ভাবনার উপর ভিত্তি করে তৈরি হয়, যার ফলে উপরে বর্ণিত বেনিফিটগুলি আরও পরিস্থিতিতে প্রয়োগ করে (হা, হা)। ডিফল্টরূপে তরঙ্গ থেকে বেরিয়ে আসা এখানে যেমন সুনির্দিষ্ট উদাহরণ থেকে প্রতীয়মান হয় তার চেয়ে আরও বেশি উপকারী হতে পারে।
সিএ ম্যাককান

ওয়াত। "কী / মান জোড়ার তালিকার একটি এবং একটি মানের কী এবং অন্যটি থেকে মানগুলির কী থেকে মান এবং একটি মানের কী"
মাতীন উলহাক

@ ম্যাটেন উলহাক এটি পূর্ববর্তী বাক্যটির ধারাবাহিকতা, যেখানে আমি অনুমান করি যে আমরা একটি কীটির উপর ভিত্তি করে একটি মান পেতে চাই এবং আমাদের তা করার দুটি উপায় রয়েছে। বাক্যটি সেই দুটি উপায়কে গণ্য করে। প্রথম উপায়ে, আপনাকে কী / মান জোড়ার একটি তালিকা দেওয়া হয়েছে এবং যে কীটির জন্য আমরা মানটি খুঁজতে চাই এবং অন্যভাবে আমাদের একটি সঠিক মানচিত্র এবং আবার একটি কী দেওয়া হবে। বাক্যটি অবিলম্বে কোডটি দেখার জন্য এটি সহায়তা করতে পারে।
বরিস

53

ব্যবহারিক উত্তর হ'ল কারী করা বেনামে ফাংশন তৈরি করা আরও সহজ করে তোলে। এমনকি একটি ন্যূনতম লাম্বদা সিনট্যাক্স সহ, এটি একটি জয়ের কিছু; তুলনা করা:

map (add 1) [1..10]
map (\ x -> add 1 x) [1..10]

আপনার যদি কুৎসিত ল্যাম্বদা সিনট্যাক্স থাকে তবে এটি আরও খারাপ। (আমি আপনাকে দেখছি, জাভাস্ক্রিপ্ট, স্কিম এবং পাইথন।)

আপনি আরও এবং আরও উচ্চতর ক্রম ফাংশন ব্যবহার করার সাথে সাথে এটি ক্রমবর্ধমান কার্যকর হয়ে ওঠে। আমি অন্যান্য ভাষার চেয়ে হাস্কেল-তে আরও উচ্চতর-আদেশ ক্রিয়াকলাপগুলি ব্যবহার করার সময়, আমি পেয়েছি যে আমি আসলে ল্যাম্বডা সিনট্যাক্সটি কম ব্যবহার করেছি কারণ লম্বদাটি আংশিকভাবে প্রয়োগ করা ফাংশন হবে the (এবং অন্যান্য সময়গুলির বেশিরভাগ সময় আমি এটি একটি নামকৃত কার্যক্রমে বের করি))

আরও মৌলিকভাবে, কোনও ক্রিয়াকলাপের কোনও সংস্করণ "ক্যানোনিকাল" এটি সর্বদা স্পষ্ট নয়। উদাহরণস্বরূপ, নিন map। প্রকারটি mapদুটি উপায়ে লেখা যায়:

map :: (a -> b) -> [a] -> [b]
map :: (a -> b) -> ([a] -> [b])

কোনটি "সঠিক"? এটি আসলে বলা শক্ত। অনুশীলনে, বেশিরভাগ ভাষা প্রথমটি ব্যবহার করে - মানচিত্রটি একটি ফাংশন এবং একটি তালিকা নেয় এবং একটি তালিকা ফেরত দেয় returns তবে, মৌলিকভাবে, ম্যাপটি আসলে যা করে তা হ'ল ফাংশনগুলি তালিকাভুক্ত করার জন্য স্বাভাবিক ফাংশনগুলি - এটি একটি ফাংশন নেয় এবং একটি ফাংশন ফিরিয়ে দেয়। যদি মানচিত্রটি ক্যারিড হয়ে থাকে তবে আপনাকে এই প্রশ্নের উত্তর দিতে হবে না: এটি উভয়ই , খুব মার্জিত উপায়ে।

আপনি mapতালিকা ব্যতীত অন্য ধরণের সাধারণকরণের পরে এটি বিশেষভাবে গুরুত্বপূর্ণ হয়ে ওঠে ।

এছাড়াও, কারী করা সত্যিই খুব জটিল নয়। বেশিরভাগ ভাষাগুলি যে মডেল ব্যবহার করেন এটির তুলনায় এটি কিছুটা সরলকরণ: আপনার ভাষায় বেকড একাধিক যুক্তিগুলির কার্যকারিতা সম্পর্কে আপনার কোনও ধারণার প্রয়োজন নেই। এটি অন্তর্নিহিত ল্যাম্বদা ক্যালকুলাসকে আরও ঘনিষ্ঠভাবে প্রতিফলিত করে।

অবশ্যই, এমএল-স্টাইলের ভাষাগুলিতে ত্রিযুক্ত বা অনিয়মিত আকারে একাধিক যুক্তির ধারণা নেই। f(a, b, c)সিনট্যাক্স আসলে tuple কথা প্রসঙ্গে অনুরূপ (a, b, c)মধ্যে f, তাই fএখনও শুধুমাত্র যুক্তি নেভিগেশন লাগে। এটি আসলে খুব দরকারী একটি পার্থক্য যা আমি আশা করি অন্যান্য ভাষাগুলির কাছে এটি থাকুক কারণ এটি এমন কিছু লিখতে খুব স্বাভাবিক করে তোলে:

map f [(1,2,3), (4,5,6), (7, 8, 9)]

আপনি যে ভাষাগুলিতে একাধিক আর্গুমেন্টের বেকড ধারণ করেছে সেগুলি দিয়ে সহজেই এটি করতে পারেন না!


1
"এমএল-স্টাইলের ভাষাগুলিতে ত্রিযুক্ত বা অনিয়মিত আকারে একাধিক যুক্তির ধারণা নেই": এই ক্ষেত্রে, হাস্কেল এমএল-স্টাইল?
জর্জিও

1
@ জর্জিও: হ্যাঁ
টিখন জেলভিস

1
মজাদার. আমি কিছু হাস্কেল জানি এবং আমি এখনই এসএমএল শিখছি, সুতরাং দুটি ভাষার মধ্যে পার্থক্য এবং মিল খুঁজে পাওয়া আকর্ষণীয়।
জর্জিও

দুর্দান্ত উত্তর, এবং যদি আপনি এখনও নিশ্চিত না
ল্যাম্বদা

"ব্যবহারিক" উত্তরটি খুব বেশি প্রাসঙ্গিক নয় কারণ ভার্চুটিটি সাধারণত আংশিক প্রয়োগ দ্বারা বর্জন করা হয়, তরকারী হয় না। এবং আমি এখানে যুক্তি দিতে পারি যে ল্যাম্বডা বিমূর্তনের সিনট্যাক্সটি (প্রকারের ঘোষণা সত্ত্বেও) স্কিমের চেয়ে (কমপক্ষে) এর চেয়ে খারাপ হয় কারণ এটি সঠিকভাবে পার্স করার জন্য আরও অন্তর্নির্মিত বিশেষ সিনট্যাক্টিক বিধিগুলির প্রয়োজন, যা কোনও লাভ ছাড়াই ভাষার বৈশিষ্টকে ফুলে যায় which শব্দার্থক বৈশিষ্ট্য সম্পর্কে।
ফ্র্যাঙ্কএইচবি

24

আপনার প্রথম কোনও শ্রেণীর অবজেক্ট হিসাবে ঘুরতে থাকা কোনও ফাংশন থাকলে এবং কোডের একটি স্থানে এটি মূল্যায়নের জন্য প্রয়োজনীয় সমস্ত প্যারামিটারগুলি না পেয়ে যদি কারিং করা কার্যকর হতে পারে। আপনি যখন এক বা একাধিক প্যারামিটারগুলি পেয়ে থাকেন তখন তা প্রয়োগ করতে পারেন এবং ফলাফলটি অন্য কোডের টুকরোতে পাস করে যার আরও বেশি পরামিতি থাকে এবং সেখানে এটির মূল্যায়ন শেষ করে finish

এটি সম্পাদন করার কোডটি আপনাকে প্রথমে সমস্ত প্যারামিটারগুলি একত্রে পাওয়া দরকারের চেয়ে সহজ হতে চলেছে।

এছাড়াও, আরও কোড পুনরায় ব্যবহারের সম্ভাবনা রয়েছে, যেহেতু একক প্যারামিটার গ্রহণকারী ফাংশনগুলিতে (অন্য কার্ডযুক্ত ফাংশন) সমস্ত পরামিতিগুলির সাথে বিশেষভাবে মেলে না।


14

তরকারী তৈরির মূল প্রেরণা (অন্তত প্রাথমিকভাবে) ব্যবহারিক ছিল না তবে তাত্ত্বিক ছিল। বিশেষত, তরঙ্গকরণ আপনাকে তাদের জন্য শব্দার্থবিজ্ঞানগুলি সংজ্ঞায়িত না করে বা পণ্যগুলির জন্য শব্দার্থবিজ্ঞানের সংজ্ঞা ছাড়াই কার্যকরভাবে মাল্টি-আর্গুমেন্ট ফাংশনগুলি পেতে দেয়। এটি অন্যটি, আরও জটিল ভাষা এবং এর মতোই স্পষ্ট প্রকাশের সাথে একটি সহজ ভাষা নিয়ে যায় এবং এটি আকাঙ্ক্ষিত।


2
যদিও এখানে অনুপ্রেরণা তাত্ত্বিক, তবুও আমি মনে করি সরলতা প্রায় সবসময় একটি ব্যবহারিক সুবিধাও বটে। মাল্টি-আর্গুমেন্ট ফাংশনগুলির বিষয়ে চিন্তা না করা আমার প্রোগ্রামকে যখন সহজতর করে তোলে তেমনি আমার জীবনকে আরও সহজ করে তোলে I
টিখন জেলভিস

2
@ টিখনজেলভিস আপনি যখন প্রোগ্রামিং করছেন, তবুও, কারিঙিং আপনাকে চিন্তিত করার জন্য অন্যান্য জিনিস দেয় যেমন সংকলক যে কোনও ফাংশনে খুব অল্প যুক্তি দিয়েছিল, এমনকি সেই ক্ষেত্রে কোনও ত্রুটির বার্তা পেয়েছে তা ধরা দেয় না; আপনি তরকারী ব্যবহার করবেন না, ত্রুটি অনেক বেশি প্রকট হয়।
অ্যালেক্স আর

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

1
ত্রুটি বার্তাগুলি ভাল হিসাবে যোগ্য হিসাবে আমি সম্মত হতে পারি না। সেবাযোগ্য, হ্যাঁ, তবে তারা এখনও ভাল নয়। এটি কেবলমাত্র এই ধরণের ইস্যুটি ধরা দেয় যদি এটির ফলে কোনও ধরণের ত্রুটি হয়, যেমন আপনি পরে যদি কোনও ফল ফাংশন ব্যতীত অন্য কিছু হিসাবে ফলাফলটি ব্যবহার করার চেষ্টা করেন (বা আপনি টীকায়িত টাইপ করেছেন তবে পাঠযোগ্য ত্রুটির জন্য নির্ভর করে তার নিজস্ব সমস্যা আছে) ); ত্রুটির প্রতিবেদন করা অবস্থানটি তার আসল অবস্থান থেকে তালাকপ্রাপ্ত।
অ্যালেক্স আর

14

(আমি হাসকেলে উদাহরণ দেব।)

  1. ক্রিয়ামূলক ভাষা ব্যবহার করার সময় এটি খুব সুবিধাজনক যে আপনি আংশিকভাবে কোনও ফাংশন প্রয়োগ করতে পারেন। হাস্কেলের মতো এটিও (== x)একটি ফাংশন যা Trueতার যুক্তি যদি একটি নির্দিষ্ট পদের সমান হয় x:

    mem :: Eq a => a -> [a] -> Bool
    mem x lst = any (== x) lst
    

    তর্ক না করেই আমাদের কিছুটা কম পঠনযোগ্য কোড থাকবে:

    mem x lst = any (\y -> y == x) lst
    
  2. এটি ট্যাসিট প্রোগ্রামিংয়ের সাথে সম্পর্কিত ( হাস্কেল উইকিতে পয়েন্টফ্রি স্টাইলটিও দেখুন )। এই শৈলীটি ভেরিয়েবল দ্বারা প্রতিনিধিত্ব করা মানগুলিতে নয়, রচনা ফাংশনগুলিতে এবং কীভাবে তথ্যগুলি ক্রিয়াকলাপের একটি শৃঙ্খলে প্রবাহিত হয় সেদিকে দৃষ্টি নিবদ্ধ করে। আমরা আমাদের উদাহরণটিকে এমন ফর্মে রূপান্তর করতে পারি যা ভেরিয়েবলগুলি মোটেও ব্যবহার করে না:

    mem = any . (==)
    

    এখানে আমরা দেখতে ==থেকে একটি ফাংশন হিসাবে aথেকে a -> Boolএবং anyথেকে একটি ফাংশন হিসাবে a -> Boolথেকে [a] -> Bool। কেবল তাদের রচনা দ্বারা, আমরা ফলাফল পেতে। এটি সব কারি করার জন্য ধন্যবাদ।

  3. বিপরীত, আন-কারিরিং, কিছু পরিস্থিতিতেও কার্যকর। উদাহরণস্বরূপ, আসুন আমরা বলি যে আমরা একটি তালিকা দুটি অংশে ভাগ করতে চাই - উপাদানগুলি যা 10 টির চেয়ে কম ছোট এবং বাকি অংশগুলি, এবং তারপরে এই দুটি তালিকাকে সংযুক্ত করে তুলতে চাই। তালিকার বিভাজন দ্বারা সম্পন্ন হয় (এখানে আমরা তরকারিও ব্যবহার করি )। ফলাফল টাইপ হয় । ফলাফলটিকে তার প্রথম এবং দ্বিতীয় অংশে বের করার পরিবর্তে এবং তাদের ব্যবহার করে একত্রিত করার পরিবর্তে আমরা অনিবার্য হয়ে সরাসরি এটি করতে পারিpartition (< 10)<([Int],[Int])++++

    uncurry (++) . partition (< 10)
    

প্রকৃতপক্ষে, (uncurry (++) . partition (< 10)) [4,12,11,1]মূল্যায়ন [4,1,12,11]

এছাড়াও গুরুত্বপূর্ণ তাত্ত্বিক সুবিধা রয়েছে:

  1. সংবাহন ভাষা ধরনের তথ্য অভাব এবং যেমন শুধুমাত্র ফাংশন, আছে জন্য অপরিহার্য ল্যামডা ক্যালকুলাস । যদিও এই ভাষাগুলি ব্যবহারিক ব্যবহারের জন্য কার্যকর নয় তবে এগুলি তাত্ত্বিক দৃষ্টিকোণ থেকে খুব গুরুত্বপূর্ণ।
  2. এটি কার্যকরী ভাষার প্রয়োজনীয় সম্পত্তিগুলির সাথে সংযুক্ত - ফাংশনগুলি হ'ল প্রথম শ্রেণীর অবজেক্ট। আমরা দেখা করেছি, থেকে রুপান্তরের (a, b) -> cজন্য a -> (b -> c)এর মানে হল যে আধুনিক ফাংশনের ফলাফলের প্রকার হল b -> c। অন্য কথায়, ফলাফলটি একটি ফাংশন।
  3. (আন) কারিঙগুলি কারটিশিয়ান বন্ধ বিভাগগুলির সাথে ঘনিষ্ঠভাবে সংযুক্ত , যা টাইপযুক্ত ল্যাম্বদা ক্যালকুলি দেখার একটি স্বতন্ত্র উপায়।

"অনেক কম পঠনযোগ্য কোড" বিটের জন্য, এটি হওয়া উচিত নয় mem x lst = any (\y -> y == x) lst? (ব্যাকস্ল্যাশ সহ)
stusmith

হ্যাঁ, এটি নির্দেশ করার জন্য ধন্যবাদ, আমি এটি সংশোধন করব।
পেটর পুদলেক

9

তরকারি শুধু সিনট্যাকটিক চিনি নয়!

add1(অনাহুত) এবং add2( ত্রিযুক্ত) ধরণের স্বাক্ষর বিবেচনা করুন :

add1 : (int * int) -> int
add2 : int -> (int -> int)

(উভয় ক্ষেত্রেই, স্বাক্ষরের প্রকারের প্রথম বন্ধনীগুলি alচ্ছিক, তবে আমি সেগুলি স্বচ্ছতার জন্য অন্তর্ভুক্ত করেছি))

add1একটি ফাংশন যে একটি 2-tuple লাগে intএবং intএবং একটি ফেরৎ intadd2এমন একটি ফাংশন যা গ্রহণ করে intএবং অন্য ফাংশন দেয় যা ঘুরে intফিরে একটি নেয় এবং একটি প্রদান করে int

দু'জনের মধ্যে প্রয়োজনীয় পার্থক্য আরও স্পষ্ট হয় যখন আমরা স্পষ্টভাবে ফাংশন অ্যাপ্লিকেশন নির্দিষ্ট করি। আসুন একটি ফাংশন সংজ্ঞায়িত করুন (তরকারী নয়) যা তার প্রথম যুক্তিকে এটির দ্বিতীয় যুক্তিতে প্রয়োগ করে:

apply(f, b) = f b

এখন আমরা মধ্যে পার্থক্য দেখতে পারেন add1এবং add2আরও স্পষ্টভাবে। add1একটি 2-টিপল দিয়ে কল করা:

apply(add1, (3, 5))

তবে add2একটি দিয়ে কল হয়ে যায় int এবং তার ফেরতের মানটিকে অন্যটির সাথে ডাকা হয়int :

apply(apply(add2, 3), 5)

সম্পাদনা: কারি করার অপরিহার্য সুবিধাটি হ'ল আপনি নিখরচায় আংশিক আবেদন পান get বলুন যে আপনি টাইপের একটি ফাংশন চান int -> int( mapএটি তালিকার উপরে এটি বলুন ) যা এর প্যারামিটারে 5 যোগ করেছে। আপনি লিখতে পারেন addFiveToParam x = x+5, বা আপনি একটি ইনলাইন ল্যাম্বডা সমতুল্য করতে পারেন, তবে আপনি আরও অনেক সহজেই করতে পারেন (বিশেষত এই ক্ষেত্রে এর চেয়ে কম তুচ্ছ) লিখতে পারেন add2 5!


3
আমি বুঝতে পারি যে আমার উদাহরণের জন্য পর্দার পিছনে একটি বিরাট বিভাজন রয়েছে, তবে ফলাফলটি একটি সাধারণ সিনট্যাকটিক পরিবর্তন বলে মনে হচ্ছে।
ম্যাড সায়েন্টিস্ট

5
কারি করানো খুব গভীর ধারণা নয়। এটি অন্তর্নিহিত মডেলটিকে সহজতর করার (ল্যাম্বদা ক্যালকুলাস দেখুন) বা যে ভাষায় দ্বিখণ্ডিত রয়েছে সেগুলিতে এটি আংশিক প্রয়োগের সিনট্যাকটিক সুবিধার্থে প্রকৃতপক্ষে। সিনট্যাকটিক সুবিধার গুরুত্বটিকে অবমূল্যায়ন করবেন না।
পিকার

9

তরঙ্গি তৈরি করা কেবল সিনট্যাকটিক চিনি, তবে চিনির কী হয় আপনি কিছুটা ভুল বুঝছেন। আপনার উদাহরণ গ্রহণ করা,

fun add x y = x + y

আসলে সিনট্যাকটিকাল চিনির জন্য

fun add x = fn y => x + y

অর্থাত, (যোগ x) এমন একটি ফাংশন প্রদান করে যা আর্গুমেন্ট y নিয়ে যায় এবং x যুক্ত করে y।

fun addTuple (x, y) = x + y

এটি একটি ফাংশন যা একটি tuple লাগে এবং এর উপাদান যোগ করে। এই দুটি ফাংশন আসলে বেশ স্বতন্ত্র; তারা বিভিন্ন যুক্তি গ্রহণ।

আপনি যদি একটি তালিকায় সমস্ত সংখ্যায় 2 যোগ করতে চান:

(* add 2 to all numbers using the uncurried function *)
map (fn x => addTuple (x, 2)) [1,2,3]
(* using the curried function *)
map (add 2) [1,2,3]

ফলাফল হবে [3,4,5]

আপনি যদি অন্য তালিকার প্রতিটি টিপলকে যোগ করতে চেয়েছিলেন তবে অন্যদিকে অ্যাডটপল ফাংশনটি পুরোপুরি ফিট করে।

(* Sum each tuple using the uncurried function *)
map addTuple [(10,2), (10,3), (10,4)]    
(* sum each tuple using curried function *)
map (fn (a,b) => add a b) [(10,2), (10,3), (10,4)]

ফলাফল হবে [12,13,14]

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

- val highestPositive = foldr Int.max 0;   
val highestPositive = fn : int list -> int 

1
আমি বুঝতে পারি যে কার্ড ফাংশনটির আলাদা ধরণের স্বাক্ষর রয়েছে এবং এটি আসলে এমন একটি ফাংশন যা অন্য ফাংশনটি ফিরিয়ে দেয়। যদিও আমি আংশিক আবেদনের অংশটি অনুপস্থিত।
ম্যাড সায়েন্টিস্ট

9

আর একটি জিনিস যা আমি এখনও উল্লেখ করি নাই তা হ'ল কারিরিং (arity) উপর সীমিত বিমূর্ততা অনুমোদন করে।

এই ফাংশনগুলি বিবেচনা করুন যা হাস্কেলের লাইব্রেরির অংশ

(.) :: (b -> c) -> (a -> b) -> a -> c
either :: (a -> c) -> (b -> c) -> Either a b -> c
flip :: (a -> b -> c) -> b -> a -> c
on :: (b -> b -> c) -> (a -> b) -> a -> a -> c

প্রতিটি ক্ষেত্রে টাইপ ভেরিয়েবল cএকটি ফাংশন টাইপ হতে পারে যাতে এই ফাংশনগুলি তাদের যুক্তির পরামিতি তালিকার কিছু উপসর্গের উপর কাজ করে। কার্চিং না করে ফাংশন আরটি থেকে বিমূর্ত করতে আপনার একটি বিশেষ ভাষা বৈশিষ্ট্য প্রয়োজন বা বিভিন্ন বৈশিষ্ট্যের জন্য বিশেষত এই ফাংশনগুলির বিভিন্ন সংস্করণ থাকতে হবে।


6

আমার সীমিত বোঝাপড়া এমন:

1) আংশিক ফাংশন অ্যাপ্লিকেশন

আংশিক ফাংশন অ্যাপ্লিকেশন হ'ল একটি ফাংশন ফিরিয়ে দেওয়ার প্রক্রিয়া যা কম সংখ্যক তর্ক যুক্ত করে। যদি আপনি 3 টির মধ্যে 2 টি আর্গুমেন্ট সরবরাহ করেন তবে এটি এমন একটি ফাংশন ফিরিয়ে দেবে যা 3-2 = 1 টি আর্গুমেন্ট নেয়। যদি আপনি 3 টির মধ্যে 1 টি আর্গুমেন্ট সরবরাহ করেন তবে এটি এমন ফাংশন ফিরিয়ে দেবে যা 3-1 = 2 টি আর্গুমেন্ট নেয়। আপনি যদি চান, আপনি এমনকি আর্গুমেন্ট 3 আউট 3 আউট প্রয়োগ করতে পারেন এবং এটি একটি ফাংশন ফিরে যে কোন যুক্তি লাগে না।

সুতরাং নিম্নলিখিত ফাংশন দেওয়া:

f(x,y,z) = x + y + z;

1 থেকে x বাঁধাই করার সময় এবং উপরের ফাংশনে আংশিকভাবে প্রয়োগ করার সময় f(x,y,z)আপনি পাবেন:

f(1,y,z) = f'(y,z);

কোথায়: f'(y,z) = 1 + y + z;

এখন আপনি যদি y তে 2 এবং z থেকে 3 বেঁধে রাখতেন এবং আংশিকভাবে প্রয়োগ f'(y,z)করতে পারেন তবে আপনি পাবেন:

f'(2,3) = f''();

যেখানে: f''() = 1 + 2 + 3;

এখন যেকোনো সময়ে, আপনি মূল্যায়ন করা চয়ন করতে পারেন f, f'অথবা f''। সুতরাং আমি এটি করতে পারি:

print(f''()) // and it would return 6;

অথবা

print(f'(1,1)) // and it would return 3;

2) তরকারী

অন্যদিকে কারি হচ্ছে একটি ফাংশনকে একটি যুক্তি ফাংশনের নেস্টেড চেইনে বিভক্ত করার প্রক্রিয়া। আপনি কখনই 1 টির বেশি যুক্তি সরবরাহ করতে পারবেন না, এটি এক বা শূন্য।

সুতরাং একই ফাংশন দেওয়া:

f(x,y,z) = x + y + z;

আপনি যদি এটি তরকারি থেকে সজ্জিত করেন তবে আপনি 3 টি ফাংশনের একটি শৃঙ্খল পাবেন:

f'(x) -> f''(y) -> f'''(z)

কোথায়:

f'(x) = x + f''(y);

f''(y) = y + f'''(z);

f'''(z) = z;

এখন আপনি যদি f'(x)সাথে কল করেন x = 1:

f'(1) = 1 + f''(y);

আপনাকে একটি নতুন ফাংশন ফিরিয়ে দেওয়া হয়েছে:

g(y) = 1 + f''(y);

আপনি যদি সাথে কল g(y)করেন y = 2:

g(2) = 1 + 2 + f'''(z);

আপনাকে একটি নতুন ফাংশন ফিরিয়ে দেওয়া হয়েছে:

h(z) = 1 + 2 + f'''(z);

শেষ পর্যন্ত যদি আপনি এই সাথে কল h(z)করেন z = 3:

h(3) = 1 + 2 + 3;

আপনি ফিরে এসেছেন 6

3) বন্ধ

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

আবার, একই ফাংশন দেওয়া:

f(x,y,z) = x + y + z;

পরিবর্তে আপনি একটি বন্ধ লিখতে পারেন:

f(x) = x + f'(y, z);

কোথায়:

f'(y,z) = x + y + z;

f'বন্ধ আছে x। এর অর্থ যা f'এর ভিতরে থাকা x এর মান পড়তে পারে f

আপনি যদি fসাথে কল করতে পারেন x = 1:

f(1) = 1 + f'(y, z);

আপনি একটি বন্ধ পেতে চাই:

closureOfF(y, z) =
                   var x = 1;
                   f'(y, z);

এখন আপনি যদি closureOfFসাথে ফোন করেন y = 2এবং z = 3:

closureOfF(2, 3) = 
                   var x = 1;
                   x + 2 + 3;

যা ফিরে আসবে 6

উপসংহার

কারিঙ, আংশিক প্রয়োগ এবং সমাপনী কিছুটা একই রকম যে তারা কোনও ফাংশনকে আরও বেশি অংশে বিভক্ত করে।

কারিঙ একাধিক যুক্তির ফাংশনকে বিরল করে যা একক যুক্তির ফাংশনগুলি ফিরিয়ে দেয় একক যুক্তির নেস্ট ফাংশনগুলিতে। এক বা কম যুক্তির ফাংশনটি কারি করার কোনও অর্থ নেই, যেহেতু এটির কোনও অর্থ নেই।

আংশিক অ্যাপ্লিকেশন একাধিক যুক্তির একটি ফাংশনকে কম আর্গুমেন্টের ফাংশনে বিভক্ত করে যার এখন অনুপস্থিত যুক্তি সরবরাহিত মানের জন্য প্রতিস্থাপন করা হয়েছিল।

বন্ধকরণ একটি ফাংশন এবং একটি ডেটাসেটের মধ্যে ফাংশনটি বিভক্ত করে যেখানে ফাংশনের অভ্যন্তরের ভেরিয়েবলগুলি যা পাস হয় নি তা মূল্যায়ন করতে বলা হলে তার সাথে বাঁধার জন্য কোনও মান সন্ধান করতে ডেটাসেটের ভিতরে দেখতে পারে look

এই সমস্ত সম্পর্কে বিভ্রান্তিকর বিষয়টি হ'ল এগুলি অন্যের একটি উপসেট বাস্তবায়নের জন্য প্রতিটি ধরণের ব্যবহার করা যেতে পারে। সুতরাং সংক্ষেপে, তারা সমস্ত কিছু বাস্তবায়ন বিশদ। এগুলি সকলেই সমান মান দেয় যে আপনাকে সমস্ত মান সম্মুখে সংগ্রহ করার দরকার নেই এবং এতে আপনি ফাংশনের অংশটি পুনরায় ব্যবহার করতে পারবেন, যেহেতু আপনি এটিকে বিচক্ষণ ইউনিটে বিভক্ত করেছেন।

প্রকাশ

আমি কোনওভাবেই এই বিষয়টির বিশেষজ্ঞ নই, আমি সম্প্রতি এইগুলি সম্পর্কে শিখতে শুরু করেছি এবং তাই আমি আমার বর্তমান বোঝাপড়াটি সরবরাহ করি তবে এতে ভুল হতে পারে যা আমি আপনাকে চিহ্নিত করার জন্য আমন্ত্রণ জানিয়েছি এবং আমি যদি / হিসাবে ঠিক করে দেব আমি কোন আবিষ্কার।


1
তাহলে উত্তরটি হল: তরকারি থেকে কোনও লাভ হয় না?
সিল্ভ করা

1
যতদূর আমি জানি, এটি সঠিক। অনুশীলনে কার্য়িং এবং আংশিক প্রয়োগ আপনাকে একই সুবিধা দেয়। কোন ভাষাতে কোন প্রয়োগটি প্রয়োগ করা যায় তা প্রয়োগের কারণে করা হয়, একটি নির্দিষ্ট ভাষা দেওয়ার পরে অন্যটি কার্যকর করা সহজ হতে পারে।
দিদিয়ের এ।

5

কারিঙ (আংশিক প্রয়োগ) আপনাকে কিছু পরামিতি স্থির করে একটি বিদ্যমান ক্রিয়াকলাপের বাইরে একটি নতুন ফাংশন তৈরি করতে দেয়। এটি লেজিকাল ক্লোজারের একটি বিশেষ ক্ষেত্রে যেখানে বেনামে ফাংশনটি কেবল একটি তুচ্ছ র‍্যাপার যা কিছু ক্যাপচারিত যুক্তিগুলি অন্য ফাংশনে পাস করে। লেক্সিকাল ক্লোজার তৈরির জন্য সাধারণ বাক্য গঠন ব্যবহার করে আমরা এটিও করতে পারি, তবে আংশিক প্রয়োগ একটি সরলিকৃত সিনট্যাকটিক চিনি সরবরাহ করে।

এ কারণেই লিস্প প্রোগ্রামারগণ কার্যকরী শৈলীতে কাজ করার সময় মাঝে মাঝে আংশিক প্রয়োগের জন্য লাইব্রেরি ব্যবহার করেন

পরিবর্তে (lambda (x) (+ 3 x)), যা আমাদের একটি ফাংশন দেয় যা তার যুক্তিতে 3 যোগ করে, আপনি এর মতো কিছু লিখতে পারেন (op + 3)এবং তাই কিছু তালিকার প্রতিটি উপাদানকে 3 যুক্ত করার (mapcar (op + 3) some-list)পরিবর্তে বরং হবে (mapcar (lambda (x) (+ 3 x)) some-list)। এই opম্যাক্রো আপনাকে একটি ফাংশন তৈরি করবে যা কিছু যুক্তি x y z ...এবং অনুরোধ গ্রহণ করে (+ a x y z ...)

অনেক খাঁটিভাবে কার্যকরী ভাষায়, কোনও opঅপারেটর না থাকায় আংশিক অ্যাপ্লিকেশনটি সিনট্যাক্সে অন্তর্ভুক্ত থাকে । আংশিক অ্যাপ্লিকেশন ট্রিগার করতে, আপনি কেবল কোনও ফাংশনটির প্রয়োজনের চেয়ে কম যুক্তি সহ কল ​​করেন। "insufficient number of arguments"ত্রুটি তৈরির পরিবর্তে ফলাফলটি বাকী যুক্তিগুলির ফাংশন।


"কার্য করা হচ্ছে ... আপনাকে কিছু প্যারামিটার ঠিক করে একটি নতুন ফাংশন তৈরি করতে দেয়" - না, টাইপের a -> b -> cকোনও ফাংশনে প্যারামিটার গুলি (বহুবচন) নেই, এটির কেবল একটি প্যারামিটার রয়েছে c,। যখন ডাকা হয়, এটি টাইপ করে একটি ফাংশন দেয় a -> b
ম্যাক্স হাইবার

4

ফাংশনের জন্য

fun add(x, y) = x + y

এটা ফর্ম হয় f': 'a * 'b -> 'c

একটি মূল্যায়ন করতে হবে

add(3, 5)
val it = 8 : int

ত্রিযুক্ত ফাংশন জন্য

fun add x y = x + y

একটি মূল্যায়ন করতে হবে

add 3
val it = fn : int -> int

যেখানে এটি একটি আংশিক গণনা, বিশেষত (3 + y), যার পরে এটির মাধ্যমে কোনওটি সম্পূর্ণ করতে পারে can

it 5
val it = 8 : int

দ্বিতীয় ক্ষেত্রে যোগ ফর্ম হয় f: 'a -> 'b -> 'c

এখানে তরকারী যা করছে তা হ'ল এমন একটি ফাংশনকে রূপান্তরিত করছে যা দুটি চুক্তিকে একটিতে রূপান্তর করে যা কেবলমাত্র ফল প্রত্যাবর্তনে এক লাগে। আংশিক মূল্যায়ন

কেন এই প্রয়োজন হবে?

xআরএইচএস সম্পর্কে বলুন কেবল একটি নিয়মিত অন্তর্নিহিত নয়, পরিবর্তে একটি জটিল গণনা যা সম্পূর্ণ করতে কিছুটা সময় নেয়, বৃদ্ধির জন্য, দুই সেকেন্ড।

x = twoSecondsComputation(z)

সুতরাং ফাংশন এখন মত দেখাচ্ছে

fun add (z:int) (y:int) : int =
    let
        val x = twoSecondsComputation(z)
    in
        x + y
    end;

টাইপ add : int * int -> int

এখন আমরা এই সংখ্যাটি বিভিন্ন সংখ্যার জন্য গণনা করতে চাই, আসুন এটি ম্যাপ করুন

val result1 = map (fn x => add (20, x)) [3, 5, 7];

উপরের জন্য ফলাফল twoSecondsComputationপ্রতি একক সময় মূল্যায়ন করা হয়। এর অর্থ এই গণনার জন্য এটি 6 সেকেন্ড সময় নেয়।

মঞ্চায়ন এবং কারিঙের সংমিশ্রণটি ব্যবহার করা এড়াতে পারে।

fun add (z:int) : int -> int =
    let
        val x = twoSecondsComputation(z)
    in
        (fn y => x + y)
    end;

তরকারিযুক্ত ফর্মের add : int -> int -> int

এখন কেউ করতে পারে,

val add' = add 20;
val result2 = map add' [3, 5, 7, 11, 13];

twoSecondsComputationশুধুমাত্র প্রয়োজন একবার মূল্যায়ন করা হবে। স্কেল আপ করতে, 15 মিনিট বা যে কোনও ঘন্টা দিয়ে দুটি সেকেন্ড প্রতিস্থাপন করুন, তারপরে 100 টি সংখ্যার বিপরীতে একটি মানচিত্র রাখুন।

সংক্ষিপ্তসার : আংশিক মূল্যায়নের একটি সরঞ্জাম হিসাবে উচ্চ স্তরের ফাংশনগুলির জন্য অন্যান্য পদ্ধতির সাথে ব্যবহার করার সময় কার্চিং দুর্দান্ত। এর উদ্দেশ্য সত্যই নিজেই প্রদর্শিত হতে পারে cannot


3

কারি করানো নমনীয় ফাংশন রচনার অনুমতি দেয়।

আমি একটি ফাংশন "তরকারী" তৈরি করেছি। এই প্রসঙ্গে, আমি কোন ধরণের লগার পাব বা কোথা থেকে এসেছে সেদিকে আমার কোনও খেয়াল নেই। অ্যাকশনটি কী বা এটি কোথা থেকে এসেছে তা আমি মাথা ঘামাই না। আমি যত্ন করি সমস্ত আমার ইনপুট প্রক্রিয়াজাত।

var builder = curry(function(input, logger, action) {
     logger.log("Starting action");
     try {
         action(input);
         logger.log("Success!");
     }
     catch (err) {
         logger.logerror("Boo we failed..", err);
     }
});
var x = "My input.";
goGatherArgs(builder)(x); // Supplies action first, then logger somewhere.

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


2

আপনার কোনও ফাংশনের জন্য সমস্ত আর্গুমেন্ট না থাকলে কড়ি করা একটি সুবিধা। আপনি যদি পুরোপুরি ফাংশনটি মূল্যায়ন করে দেখেন তবে তাৎপর্যপূর্ণ কোনও পার্থক্য নেই।

কারিরিং আপনাকে অ-এখনও-প্রয়োজনীয় প্যারামিটারগুলি উল্লেখ এড়াতে দেয়। এটি আরও সংক্ষিপ্ত, এবং এমন কোনও প্যারামিটারের নাম সন্ধানের প্রয়োজন নেই যা স্কোপটিতে অন্য পরিবর্তনশীল (যা আমার প্রিয় উপকার) এর সাথে সংঘর্ষে আসে না।

উদাহরণস্বরূপ, যখন ফাংশনগুলি আর্গুমেন্ট হিসাবে গ্রহণ করে তখন আপনি প্রায়শই নিজেকে এমন পরিস্থিতিতে খুঁজে পাবেন যেখানে "ইনপুটটিতে 3 যুক্ত করুন" বা "ইনপুটকে ভেরিয়েবলের সাথে তুলনা করুন" এর মতো ফাংশনগুলির প্রয়োজন। কার্চিংয়ের সাথে, এই ফাংশনগুলি সহজেই লিখিত হয়: add 3এবং (== v)। কারিঙ না করে, আপনাকে ল্যাম্বদা এক্সপ্রেশন: x => add 3 xএবং ব্যবহার করতে হবে x => x == v। ল্যাম্বডা এক্সপ্রেশনগুলি দ্বিগুণ দীর্ঘ এবং xএর মধ্যে ইতিমধ্যে কোনও xসুযোগ থাকলেও নাম বাছাইয়ের সাথে সামান্য পরিমাণে ব্যস্ত কাজ রয়েছে ।

কার্বিংয়ের উপর ভিত্তি করে ভাষার একটি পার্শ্ব সুবিধা হ'ল, ফাংশনগুলির জন্য জেনেরিক কোড লেখার সময়, আপনি পরামিতিগুলির সংখ্যার উপর ভিত্তি করে শত শত রূপগুলি দিয়ে শেষ করবেন না। উদাহরণস্বরূপ, সি # তে, 'কারি' পদ্ধতির জন্য ফানক <আর>, ফানক <এ, আর>, ফানক <এ 1, এ 2, আর>, ফানক <এ 1, এ 2, এ 3, আর> এবং আরও অনেকের জন্য রূপগুলি প্রয়োজন চিরতরে. হাসকেলে, একটি ফানক <এ 1, এ 2, আর> এর সমতুল্য আরও বেশি একটি ফান্চ <টিউপল <এ 1, এ 2>, আর> বা ফানক <এ 1, ফানক <এ 2, আর >> (এবং একটি ফানক <আর> আরও একটি ফানক <ইউনিট, আর>) এর মতো, তাই সমস্ত রূপগুলি একক ফানক <এ, আর> কেসের সাথে মিলে যায়।


2

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


1
ঠিক কীভাবে আরও অনেকগুলি স্ট্যাক ফ্রেম তৈরি করা প্রয়োজন যাতে জিনিসগুলি আরও দক্ষ করে তোলে?
ম্যাসন হুইলারের

1
@ মেসনওহিলার: আমি জানতাম না, কারণ আমি বলেছি যে আমি কার্যকরী ভাষা বা বিশেষত কারিঙের বিশেষজ্ঞ নই। আমি এই সম্প্রদায়ের উইকিটিকে বিশেষত কারণ হিসাবে লেবেল করেছি।
জোয়েল ইথারটন

4
@ ম্যাসনওহিলার আপনার এই উত্তরটির বাক্যটি রচনা করতে পারে, তবে আমাকে চিপ করে বলতে দিন যে স্ট্যাক ফ্রেমের পরিমাণটি বাস্তবে তৈরি হয়েছে তা বাস্তবায়নের উপর অনেক বেশি নির্ভর করে। উদাহরণস্বরূপ, মেরুদণ্ডবিহীন ট্যাগহীন জি মেশিনে (এসটিজি; জিএইচসি যেভাবে হাস্কেল প্রয়োগ করে) প্রকৃত মূল্যায়ন বিলম্ব না করে যতক্ষণ না এটি সমস্ত (বা কমপক্ষে এটি প্রয়োজনীয় হিসাবে জানে) যুক্তিগুলি সংগ্রহ করে না। এটি সমস্ত ফাংশনগুলির জন্য বা কেবল নির্মাতাদের জন্য করা হয়েছে কিনা তা আমি মনে করতে পারি না, তবে আমি মনে করি এটি বেশিরভাগ ফাংশনের জন্যই সম্ভব হওয়া উচিত। (তারপরে আবার "স্ট্যাক ফ্রেমগুলি" ধারণাটি

1

কারিঙ্কিং কোনও ক্রিয়াকলাপ ফেরানোর ক্ষমতার উপর অত্যন্ত গুরুত্বপূর্ণ (নির্ধারিত এমনকি))

এটি (অনুমোদিত) সিউডো কোডটি বিবেচনা করুন।

var f = (মি, এক্স, বি) => ... কিছু ফিরিয়ে দিন ...

আসুন নির্ধারণ করি যে তিনটি আর্গুমেন্টের চেয়ে কম কল দিয়ে একটি ফাংশন দেয় returns

var g = f (0, 1); // এটি 0 এবং 1 (মি এবং এক্স) এর সাথে আবদ্ধ একটি ফাংশন দেয় যা আরও একটি যুক্তি (খ) গ্রহণ করে।

var y = g (42); // মি এবং এক্স এর জন্য 0 এবং 1 ব্যবহার করে, অনুপস্থিত তৃতীয় আর্গুমেন্টের সাথে জিপ করুন g

আপনি আংশিকভাবে যুক্তি প্রয়োগ করতে পারেন এবং পুনরায় ব্যবহারযোগ্য ফাংশনটি ফিরে পেতে পারেন (আপনি যে সরবরাহ করেছিলেন সেই যুক্তিগুলির সাথে আবদ্ধ) যথেষ্ট কার্যকর (এবং ডিআরওয়াই) is

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