'কারিিং' কী?


652

আমি বেশ কয়েকটি নিবন্ধ এবং ব্লগে তরকারী ফাংশনগুলির রেফারেন্স দেখেছি তবে আমি একটি ভাল ব্যাখ্যা খুঁজে পাচ্ছি না (বা কমপক্ষে একটি যা বোঝায়!)


12
[একটি মন্তব্য হিসাবে বাম, যেহেতু এটি অ-গণিতবিদদের কাছে অকার্যকর হবে।] কার্টেসিয়ান বদ্ধ শ্রেণির সংজ্ঞা অনুসারে, এক্স -> এক্স এক্স এ এবং এক্স এর মধ্যে অ্যাডজ্যাঙ্কশনগুলির একটি নির্দিষ্ট পরিবার রয়েছে (প্রাকৃতিকভাবে এ দ্বারা প্যারামাইট্রাইজড) -> এক্স ^ এ আইসোমর্ফিজম হোম (এক্স এক্স এ, ওয়াই) <-> হোম (এক্স, ওয়াই ^ এ) হ্যাস্কেলের কাজ curryএবং uncurryক্রিয়াকলাপ। এখানে গুরুত্বপূর্ণ বিষয় হ'ল এই আইসোমর্ফিজমগুলি আগে থেকেই ঠিক করা হয়েছে, এবং তাই ভাষায় "অন্তর্নির্মিত"।
আলেকজান্দ্রি সি

3
সেখানে একটা চমৎকার টিউটোরিয়াল এখানে মধ্যে Haskell সংবাহন জন্য learnyouahaskell.com/higher-order-functions#curried-functions সংক্ষিপ্ত মন্তব্য করে add x y = x+y(curried) এর ভিন্ন add (x, y)=x+y(uncurried)
Jaider

উত্তর:


871

কারিং হচ্ছে যখন আপনি কোনও ফাংশনটি ভাঙেন যা একাধিক যুক্তিগুলি ক্রিয়াকলাপের একটি সিরিজে নিয়ে যায় যা প্রত্যেকে কেবল একটি যুক্তি নেয়। জাভাস্ক্রিপ্টে এখানে একটি উদাহরণ রয়েছে:

function add (a, b) {
  return a + b;
}

add(3, 4); // returns 7

এটি এমন একটি ফাংশন যা দুটি আর্গুমেন্ট গ্রহণ করে, ক এবং খ এবং তাদের যোগফল দেয়। আমরা এখন এই ফাংশনটি কারি করব:

function add (a) {
  return function (b) {
    return a + b;
  }
}

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

add(3)(4);

var add3 = add(3);

add3(4);

অ্যাড (3, 4) স্টেটমেন্টের মতো প্রথম স্টেটমেন্টটি 7 দেয়। দ্বিতীয় বিবৃতিটি যুক্ত 3 নামে একটি নতুন ফাংশন সংজ্ঞায়িত করে যা তার যুক্তিতে 3 যোগ করবে। এটি কিছু লোককে ক্লোজার বলা হতে পারে। তৃতীয় বিবৃতিটি 3 থেকে 4 যোগ করতে অ্যাড 3 অপারেশন ব্যবহার করে, ফলস্বরূপ 7 টি উত্পাদন করে।


235
ব্যবহারিক অর্থে, আমি এই ধারণাটি কীভাবে ব্যবহার করতে পারি?
স্ট্রবেরি

43
@ স্ট্রাবেরি, উদাহরণস্বরূপ বলুন যে আপনার একটি সংখ্যার একটি তালিকা রয়েছে [1, 2, 3, 4, 5]যা আপনি একটি স্বেচ্ছাসেবী সংখ্যা দ্বারা গুণ করতে চান। হাস্কেল-এ, আমি map (* 5) [1, 2, 3, 4, 5]পুরো তালিকাটি গুণ করে লিখতে পারি 5এবং এইভাবে তালিকা তৈরি করে [5, 10, 15, 20, 25]
নিসন

62
আমি মানচিত্রের ফাংশনটি কী করে তা বুঝতে পেরেছি তবে আপনি আমার জন্য উদাহরণটি বর্ণনা করার চেষ্টা করছেন এমন পয়েন্টটি আমি বুঝতে পেরেছি কিনা তা নিশ্চিত নই। আপনি কি বলছেন যে মানচিত্রের ফাংশন কারিঙের ধারণার প্রতিনিধিত্ব করে?
স্ট্রবেরি

78
@ স্ট্রাবেরি প্রথম যুক্তিটি mapএকটি ফাংশন হতে হবে যা কেবলমাত্র 1 টি যুক্তি লাগে - তালিকা থেকে একটি উপাদান। গুণ - একটি গাণিতিক ধারণা হিসাবে - একটি বাইনারি অপারেশন; এটি 2 টি আর্গুমেন্ট লাগে। তবে, *হাসকেলে একটি উত্তেজিত ফাংশন, addএই উত্তরের দ্বিতীয় সংস্করণের অনুরূপ । এর ফলাফলটি (* 5)এমন একটি ফাংশন যা একক যুক্তি নেয় এবং এটি 5 দিয়ে গুণ করে এবং যা আমাদের মানচিত্রের সাহায্যে এটি ব্যবহার করতে দেয় allows
ডোভাল

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

125

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

সুতরাং, এমন কোনও কিছুকে আপনি কীভাবে মোকাবেলা করবেন যা আপনি প্রাকৃতিকভাবে বলেছিলেন, বলুন f(x,y)? ঠিক আছে, আপনি এটি সমান হিসাবে গ্রহণ f(x)(y)- f(x)এটি কল g, একটি ফাংশন, এবং আপনি এই ফাংশন প্রয়োগ y। অন্য কথায়, আপনার কেবলমাত্র একটি ফাংশন রয়েছে যা একটি যুক্তি গ্রহণ করে - তবে এই ফাংশনগুলির মধ্যে কিছু অন্য ফাংশন দেয় (যা ALSO একটি যুক্তি গ্রহণ করে ;-)।

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


1
আমি আমার উপরের মত একই মন্তব্য মনে করি - আমি দেখিনি যে কার্যকরী ভাষাগুলি একটি একক আরগ নেওয়ার ক্ষেত্রে ফাংশনকে সীমাবদ্ধ করে। আমি কি ভুল করছি?
এরিক এম

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

1
ঠিক আছে. আরও একটি প্রশ্ন। নিম্নলিখিতটি কি সত্য বক্তব্য? লাম্বদা ক্যালকুলাস ফাংশনাল প্রোগ্রামিংয়ের মডেল হিসাবে ব্যবহার করা যেতে পারে তবে ফাংশনাল প্রোগ্রামিং লাম্বদা ক্যালকুলাস প্রয়োগ করা হয় না।
এরিক এম

7
উইকিপিডিয়া পৃষ্ঠাগুলি নোট হিসাবে, বেশিরভাগ এফপি ভাষাগুলি কেবল "প্রয়োগ" না করে বেশিরভাগ এফপি ভাষাগুলি "শোভিত" বা "বর্ধমান" ল্যাম্বডা ক্যালকুলাস (যেমন কয়েকটি ধ্রুবক এবং ডেটাটাইপ সহ), তবে এটি খুব কাছাকাছি নয়। বিটিডাব্লু, আপনাকে কী এমন ধারণা দেয় যে উদাহরণস্বরূপ হাস্কেল "একক আরগ নেওয়ার ক্ষেত্রে ফাংশনকে সীমাবদ্ধ করে না"? এটি নিশ্চিত করে, তবুও এটি কার্চিংয়ের জন্য অপ্রাসঙ্গিক ধন্যবাদ; যেমন div :: Integral a => a -> a -> a- multiple একাধিক তীরগুলি নোট করুন? "একটিতে ম্যাপিং ফাংশন করতে মানচিত্র" একটি পঠন ;-)। আপনি & সি এর জন্য একটি (একক) টিপল আর্গুমেন্ট ব্যবহার করতে পারেন divতবে এটি হাস্কেলের সত্যই অ্যান্টি-আইডিয়োমেটিক হবে।
অ্যালেক্স মার্তেলি

@ অ্যালেক্স - হার্ট হাসেল এবং যুক্ত গণনা, আমি হাস্কেলের জন্য খুব বেশি সময় ব্যয় করি নি, এবং কয়েক সপ্তাহ আগে এটিই ছিল। সুতরাং এটি করা সহজ ত্রুটি ছিল।
এরিক এম

99

এখানে একটি দৃ concrete় উদাহরণ:

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

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


2
কৌতূহল হিসাবে, জাভাস্ক্রিপ্টের জন্য প্রোটোটাইপ লাইব্রেরি একটি "কারি" ফাংশন সরবরাহ করে যা আপনি এখানে যা ব্যাখ্যা করেছেন ঠিক
তেমনভাবে করে

নতুন প্রোটোটাইপজেএস কারি ফাংশন লিঙ্ক। প্রোটোটাইপজেস.আর.অর্গ
ডক / স্লেস্ট / ভাষাগুলি / ফাংশন /

7
এটি আমার কাছে আংশিক প্রয়োগের মতো শোনাচ্ছে। আমার বোধগম্যতা হল আপনি যদি কারিঙ প্রয়োগ করেন তবে আপনি একটি যুক্তি দিয়ে ফাংশন তৈরি করতে এবং আরও জটিল ফাংশন গঠনের জন্য তাদের রচনা করতে পারেন। আমি কিছু অনুপস্থিত করছি?
নিওন্টাপির

9
পছন্দ করুন শেয়া যা বর্ণনা করেছে তা কারি হচ্ছে না। এটি আংশিক প্রয়োগ। যদি কোনও ত্রি-যুক্তি ফাংশনটি ক্যারিড হয়ে থাকে এবং আপনি এটিকে চ (1) হিসাবে কল করেন তবে আপনি যা ফিরে পাবেন তা দ্বি-যুক্তির কার্য নয়। আপনি একটি ওয়ান-আর্গুমেন্ট ফাংশন ফিরে পাবেন যা অন্য এক-যুক্তি ফাংশনটি ফিরিয়ে দেয়। একটি ত্রিযুক্ত ফাংশন কেবল কখনওই একটি যুক্তি পাস করা যায়। প্রোটোটাইপজেএস-এ কারি ফাংশনটিও কারি হচ্ছে না। এটি আংশিক প্রয়োগ।
MindJuice

না (আংশিক মূল্যায়নের জন্য) এবং না (কার্চিংয়ের জন্য)। এটি আংশিক প্রয়োগ হিসাবে পরিচিত as এটি সক্ষম করার জন্য কার্চিংয়ের প্রয়োজন।
নেস

47

কারি করা হ'ল এমন রূপান্তর যা ফাংশনে প্রয়োগ করা যেতে পারে যাতে তারা আগের তুলনায় একটি কম যুক্তি নিতে পারে।

উদাহরণস্বরূপ, এফ # তে আপনি এভাবে কোনও ফাংশন সংজ্ঞায়িত করতে পারেন: -

let f x y z = x + y + z

এখানে ফাংশন এক্স প্যারামিটারগুলি x, y এবং z নেয় এবং তাদের একসাথে যোগ করে তোলে: -

f 1 2 3

ফিরে আসে 6।

আমাদের সংজ্ঞা থেকে আমরা চ এর জন্য কারি ফাংশনটি সংজ্ঞায়িত করতে পারি:

let curry f = fun x -> f x

যেখানে 'মজাদার x -> fx' হল সি # তে x => f (x) এর সমতুল্য একটি ল্যাম্বডা ফাংশন। এই ফাংশনটি আপনি কারি করতে চান এমন ফাংশনটি ইনপুট করে এবং এমন একটি ফাংশন প্রদান করে যা একটি একক আর্গুমেন্ট নেয় এবং নির্দিষ্ট ফাংশনটিকে প্রথম যুক্তিটি ইনপুট আর্গুমেন্টে সেট করে দেয়।

আমাদের আগের উদাহরণটি ব্যবহার করে আমরা চ এর একটি কারি পেতে পারি: -

let curryf = curry f

তারপরে আমরা নিম্নলিখিতগুলি করতে পারি: -

let f1 = curryf 1

যা আমাদের এফ 1 ফাংশন সরবরাহ করে যা f1 yz = 1 + y + z এর সাথে সমান। এর অর্থ আমরা নিম্নলিখিতগুলি করতে পারি: -

f1 2 3

যা প্রত্যাবর্তন 6।

এই প্রক্রিয়াটি প্রায়শই 'আংশিক ফাংশন অ্যাপ্লিকেশন' দিয়ে বিভ্রান্ত হয় যা এইভাবে সংজ্ঞায়িত করা যায়: -

let papply f x = f x

যদিও আমরা এটিকে একাধিক প্যারামিটারে প্রসারিত করতে পারি, যেমন: -

let papply2 f x y = f x y
let papply3 f x y z = f x y z
etc.

একটি আংশিক অ্যাপ্লিকেশনটি ফাংশন এবং প্যারামিটার গ্রহণ করবে এবং এমন ফাংশন ফিরিয়ে দেবে যার জন্য এক বা একাধিক কম পরামিতি প্রয়োজন, এবং পূর্ববর্তী দুটি উদাহরণ শো হিসাবে সরাসরি স্ট্যান্ডার্ড এফ # ফাংশন সংজ্ঞাতে প্রয়োগ করা হয়েছে যাতে আমরা পূর্ববর্তী ফলাফলটি এভাবে অর্জন করতে পারি: -

let f1 = f 1
f1 2 3

যা 6 এর ফলাফল ফিরিয়ে দেবে।

উপসংহারে:-

কারিং এবং আংশিক ফাংশন অ্যাপ্লিকেশন মধ্যে পার্থক্য হ'ল: -

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

let f x y z = x + y + z
let curryf = curry f
let f1 = curryf 1
let f2 = curryf 2
f1 2 3
6
f2 1 3
6

আংশিক ফাংশন অ্যাপ্লিকেশনটি আরও সরাসরি - এটি একটি ফাংশন এবং এক বা একাধিক আর্গুমেন্ট নেয় এবং নির্দিষ্ট এন আর্গুমেন্টে সেট করা প্রথম এন আর্গুমেন্টের সাথে একটি ফাংশন প্রদান করে। উদাহরণ: -

let f x y z = x + y + z
let f1 = f 1
let f2 = f 2
f1 2 3
6
f2 1 3
6

সুতরাং সি # তে পদ্ধতিগুলি আংশিকভাবে প্রয়োগ করার আগে সেগুলি করা দরকার?
সিডিএমকেই

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

44

এটি অন্যান্য ফাংশনগুলি করতে ফাংশনগুলি ব্যবহার করার একটি উপায় হতে পারে।

জাভাস্ক্রিপ্টে:

let add = function(x){
  return function(y){ 
   return x + y
  };
};

আমাদের এটিকে এভাবে কল করার অনুমতি দেবে:

let addTen = add(10);

এই রান যখন 10হিসাবে হিসাবে পাস হয় x;

let add = function(10){
  return function(y){
    return 10 + y 
  };
};

যার অর্থ আমরা এই ফাংশনটি ফিরে পেয়েছি:

function(y) { return 10 + y };

সুতরাং আপনি কল যখন

 addTen();

আপনি সত্যিই কল করছেন:

 function(y) { return 10 + y };

সুতরাং আপনি যদি এটি করেন:

 addTen(4)

এটি যেমন:

function(4) { return 10 + 4} // 14

সুতরাং আমাদের addTen()সর্বদা আমরা যা যা করি তাতে দশটি যুক্ত হয় We আমরা একইভাবে একই রকম ফাংশন করতে পারি:

let addTwo = add(2)       // addTwo(); will add two to whatever you pass in
let addSeventy = add(70)  // ... and so on...

এখন সুস্পষ্ট ফলোআপ প্রশ্ন হ'ল পৃথিবীতে আপনি কখনই তা করতে চান কেন? এটি এমন এক উত্সাহী অপারেশনকে x + yরূপান্তরিত করে যা অলসতার মধ্য দিয়ে পদক্ষেপ নেওয়া যায়, যার অর্থ আমরা কমপক্ষে দুটি জিনিস করতে পারি 1. ব্যয়বহুল অপারেশনকে ক্যাশে করুন 2. কার্যকরী দৃষ্টান্তে বিমূর্ততা অর্জন করুন।

কল্পনা করুন যে আমাদের কার্ড ফাংশনটি এমন দেখাচ্ছে:

let doTheHardStuff = function(x) {
  let z = doSomethingComputationallyExpensive(x)
  return function (y){
    z + y
  }
}

আমরা একবার এই ফাংশনটি কল করতে পারি, তারপরে ফলাফলটি প্রচুর জায়গায় ব্যবহার করার জন্য পাস করতে পারি, যার অর্থ আমরা কেবলমাত্র গণ্য ব্যয়বহুল জিনিসগুলি একবার করে করি:

let finishTheJob = doTheHardStuff(10)
finishTheJob(20)
finishTheJob(30)

আমরা একইভাবে বিমূর্ততা পেতে পারি।


5
আমি এখানে দেখেছি এমন অন্তর্নিহিত ক্রমিক ক্রিয়াকলাপের ধাপে ধাপে সেরা ধাপ এবং লটের সেরা, সবচেয়ে ব্যাখ্যামূলক উত্তর।

4
@ জোনসিলভার আমি বিপরীতে বলব, ভাল ব্যাখ্যা নয়। আমি সম্মত উদাহরণটি ব্যাখ্যা করার পক্ষে এটি ভাল, তবে লোকেরা চিন্তাভাবনার দিকে ঝুঁকছে, "হ্যাঁ পুরোপুরি স্পষ্ট তবে আমি একই জিনিসটি অন্য উপায়ে করতে পারতাম তাই ভাল কি করছিল?" অন্য কথায়, আমি আশা করি এটি কেবল কারিরিং কীভাবে কাজ করে তা আলোকিত করার জন্য পর্যাপ্ত প্রসঙ্গ বা ব্যাখ্যা থাকতে পারে, তবে কেন দশটি যুক্ত করার অন্যান্য পদ্ধতির তুলনায় এটি কেন অকেজো এবং তুচ্ছ পর্যবেক্ষণ নয়।
হোয়াইটনিল্যান্ড

29

একটি ত্রিযুক্ত ফাংশন হ'ল বিভিন্ন আর্গুমেন্টের এমন একটি ফাংশন যা এটি পুনরায় লিখিত হয় যে এটি প্রথম যুক্তিটি গ্রহণ করে এবং এমন একটি ফাংশন প্রদান করে যা দ্বিতীয় তর্কটিকে গ্রহণ করে এবং এইভাবে। এটি বেশ কয়েকটি আর্গুমেন্টের ফাংশনগুলিকে তাদের কিছু প্রাথমিক আর্গুমেন্ট আংশিকভাবে প্রয়োগ করার অনুমতি দেয়।


5
"এটি বেশ কয়েকটি আর্গুমেন্টের ফাংশনগুলিকে তাদের প্রাথমিক আর্গুমেন্টগুলির আংশিকভাবে প্রয়োগ করার অনুমতি দেয়।" - কেন এটি উপকারী?
একারলন

5
@ একারলন ফাংশনগুলি প্রায়শই বারে বারে এক বা একাধিক তর্ক যুক্ত হয়ে ডাকা হয়। উদাহরণস্বরূপ, আপনি যদি তালিকাগুলির তালিকার উপরে কোনও mapফাংশন করতে চান তবে আপনি করতে পারেন । fxssmap (map f) xss
জন হ্যারোপ 5'13

1
আপনাকে ধন্যবাদ, এটি উপলব্ধি করে। আমি আরও কিছুটা পড়া করেছি এবং এটি জায়গায় পড়েছে।
একারলন

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

7

পাইথনের খেলনার উদাহরণ এখানে:

>>> from functools import partial as curry

>>> # Original function taking three parameters:
>>> def display_quote(who, subject, quote):
        print who, 'said regarding', subject + ':'
        print '"' + quote + '"'


>>> display_quote("hoohoo", "functional languages",
           "I like Erlang, not sure yet about Haskell.")
hoohoo said regarding functional languages:
"I like Erlang, not sure yet about Haskell."

>>> # Let's curry the function to get another that always quotes Alex...
>>> am_quote = curry(display_quote, "Alex Martelli")

>>> am_quote("currying", "As usual, wikipedia has a nice summary...")
Alex Martelli said regarding currying:
"As usual, wikipedia has a nice summary..."

(পাইথনবিহীন প্রোগ্রামারদের বিভ্রান্তি এড়াতে কেবলমাত্র + মাধ্যমে কনটেক্সটেশন ব্যবহার করা))

যুক্ত করতে সম্পাদনা:

Http://docs.python.org/library/functools.html?hightlight=partial#functools.partial দেখুন , যা পাইথন এটি প্রয়োগের ক্ষেত্রে আংশিক বস্তু বনাম ফাংশন পার্থক্য দেখায়।


আমি এটি পাই না - আপনি এটি করুন: >>> am_quote = তরকারী (প্রদর্শন_কোটা, "অ্যালেক্স মার্টেলি") তবে তারপরে আপনি এটি পরবর্তী করুন: >>> am_quote ("তরকারী"), "যথারীতি উইকিপিডিয়ায় একটি দুর্দান্ত সংক্ষিপ্তসার রয়েছে। .. ") সুতরাং আপনার দুটি ফর্ম রয়েছে gs দেখে মনে হচ্ছে যে কারিগরি করা আপনাকে তিনটি আলাদা ফানক দেয় যা আপনি রচনা করেছিলেন?
এরিক এম

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

(বিটিডব্লিউ - '>>>' হ'ল কোডের অংশ নয়, পাইথন ইন্টারেক্টিভ ইন্টারপ্রেটারে প্রম্পট))
আনন

ঠিক আছে আরগস সম্পর্কে স্পষ্টতার জন্য ধন্যবাদ। পাইথন ইন্টারপ্রেটার প্রম্পট সম্পর্কে আমি জানি, আমি লাইনগুলি উদ্ধৃত করার চেষ্টা করছিলাম কিন্তু এটি কার্যকর হয়নি ;-)
এরিক এম

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

5

কারিিং কলযোগ্য থেকে একটি ফাংশন হিসাবে কলযোগ্য হিসাবে অনুবাদ f(a, b, c)করা হয় f(a)(b)(c)

অন্যথায় কার্চিং হ'ল যখন আপনি কোনও ফাংশন ভাঙ্গেন যা একাধিক যুক্তিগুলি বিভিন্ন ক্রিয়ায় যুক্ত করে যা আর্গুমেন্টের অংশ নেয়।

আক্ষরিক অর্থে, কারিঙ করা একটি ক্রিয়াকলাপের রূপান্তর: অন্য দিকে কল করার এক উপায় থেকে। জাভাস্ক্রিপ্টে, আমরা সাধারণত মূল ফাংশন রাখতে একটি মোড়ক তৈরি করি।

কারিং করা কোনও ফাংশন কল করে না। এটি কেবল এটি রূপান্তরিত করে।

আসুন কারি ফাংশন তৈরি করি যা দ্বি-যুক্তি ফাংশনের জন্য কারিটিং সম্পাদন করে। অন্য কথায়, curry(f)দ্বি-যুক্তির জন্য f(a, b)এটি অনুবাদ করেf(a)(b)

function curry(f) { // curry(f) does the currying transform
  return function(a) {
    return function(b) {
      return f(a, b);
    };
  };
}

// usage
function sum(a, b) {
  return a + b;
}

let carriedSum = curry(sum);

alert( carriedSum(1)(2) ); // 3

আপনি দেখতে পাচ্ছেন, বাস্তবায়ন হ'ল র‌্যাপের একটি ধারা।

  • এর ফলাফলটি curry(func)একটি মোড়কের function(a)
  • যখন এটির মতো বলা হয় sum(1), যুক্তিটি লেক্সিকাল এনভায়রনমেন্টে সংরক্ষণ করা হয় এবং একটি নতুন মোড়ক ফিরে আসে function(b)
  • তারপরে sum(1)(2)অবশেষে function(b)2 সরবরাহকারী কলগুলি কল করে এবং এটি কলটি মূল মাল্টি-আর্গুমেন্টের যোগে যায়।

4

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

ক্লোজুরে ইন +একটি ফাংশন তবে বিষয়গুলি একেবারে পরিষ্কার করে দেওয়া:

(defn add [a b] (+ a b))

আপনি সচেতন হতে পারেন যে incফাংশনটি যে কোনও সংখ্যায় পাস করেছে।

(inc 7) # => 8

আসুন এটি ব্যবহার করে আমরা এটি তৈরি করি partial:

(def inc (partial add 1))

এখানে আমরা আবার একটি ফাংশন ফিরিয়েছি যা 1 এর প্রথম তর্কটিতে লোড হয়েছে add। হিসাবে addদুটি আর্গুমেন্ট লাগে নতুন incফাংশনটি কেবল bযুক্তি চায় - 1 টি ইতিমধ্যে আংশিকভাবে প্রয়োগ করা হয়েছে এর আগে 2 টি আর্গুমেন্ট নয় । এভাবে partialএকটি টুল যা থেকে presupplied ডিফল্ট মান সাথে নতুন ফাংশন তৈরি হয়। একারণে একটি কার্যকরী ভাষার কার্যক্রমে প্রায়শই সাধারণ থেকে নির্দিষ্টকে যুক্তিগুলি অর্ডার করে। এটি এমন ফাংশনগুলি পুনরায় ব্যবহার করা সহজ করে যার থেকে অন্যান্য ফাংশনগুলি তৈরি করা যায়।

এখন ভাবুন যে ভাষাটি অন্তর্নিজ্ঞাতভাবে বুঝতে যথেষ্ট স্মার্ট ছিল যে addদুটি যুক্তি চেয়েছিল। যখন আমরা এটিকে ঝাঁকুনির পরিবর্তে একটি যুক্তিটি পাস করি, তখন যদি ফাংশনটি আংশিকভাবে যুক্তিটি প্রয়োগ করে আমরা আমাদের পক্ষ থেকে বুঝতে পারি যে সম্ভবত আমরা অন্য যুক্তিটি পরে সরবরাহ করতে চাইছি তা বুঝে? আমরা তখন সংজ্ঞায়িত করতে পারে incস্পষ্টভাবে ব্যবহার না করেই partial

(def inc (add 1)) #partial is implied

কিছু ভাষার আচরণ এইভাবে হয়। এটি ব্যতিক্রমীভাবে কার্যকর যখন কেউ ফাংশনগুলি বৃহত্তর রূপান্তরগুলিতে রচনা করতে চান। এটি ট্রান্সডুসারগুলিতে নেতৃত্ব দেবে।


3

আমি এই নিবন্ধে, এবং নিবন্ধ এটা উল্লেখ দরকারী পাওয়া, ভাল সংবাহন বুঝতে: http://blogs.msdn.com/wesdyer/archive/2007/01/29/currying-and-partial-function-application.aspx

অন্যরা যেমন উল্লেখ করেছে, এটি কেবলমাত্র একটি প্যারামিটারের কাজ করার উপায়।

এটি দরকারী যে এতে আপনাকে কতটা প্যারামিটার পাস হবে তা ধরে নিতে হবে না, সুতরাং আপনার কোনও 2 প্যারামিটার, 3 প্যারামিটার এবং 4 পরামিতি ফাংশন প্রয়োজন নেই।


3

অন্যান্য সমস্ত উত্তর কারিরিং আংশিকভাবে প্রয়োগকৃত কার্যগুলি তৈরি করতে সহায়তা করে। জাভাস্ক্রিপ্ট স্বয়ংক্রিয় কারি করার জন্য স্থানীয় সমর্থন সরবরাহ করে না। সুতরাং উপরোক্ত উদাহরণগুলি ব্যবহারিক কোডিংয়ে সহায়তা নাও করতে পারে। লাইফস্ক্রিপ্টে কিছু দুর্দান্ত উদাহরণ রয়েছে (যা মূলত জেএসগুলিতে সংকলিত হয়) http://livescript.net/

times = (x, y) --> x * y
times 2, 3       #=> 6 (normal use works as expected)
double = times 2
double 5         #=> 10

উপরের উদাহরণে যখন আপনি কম আর্গুমেন্ট দিয়েছিলেন লাইফস্ক্রিপ্ট আপনার জন্য নতুন ক্রিড ফাংশন তৈরি করে (ডাবল)


3

কারি আপনার কোডটি সহজতর করতে পারে। এটি ব্যবহারের এটি অন্যতম প্রধান কারণ। কারিং হ'ল একটি ফাংশনকে রূপান্তর করার একটি প্রক্রিয়া যা এন আর্গুমেন্টগুলিকে n ফাংশনগুলিতে গ্রহণ করে যা কেবল একটি যুক্তি গ্রহণ করে।

নীতিটি হ'ল পাসের ফাংশনটির যুক্তিগুলি পাসওয়ার্ড (ক্লোজার) প্রপার্টিটি ব্যবহার করে অন্য ফাংশনে সংরক্ষণ করে এটির ফেরত মূল্য হিসাবে বিবেচনা করা হয় এবং এই ফাংশনগুলি একটি শৃঙ্খলা তৈরি করে এবং চূড়ান্ত যুক্তিগুলি শেষ করার জন্য পাস হয় অপারেশন.

এর সুবিধাটি হ'ল এটি একবারে একটি প্যারামিটার নিয়ে কাজ করে প্যারামিটারগুলির প্রসেসিং সহজ করতে পারে যা প্রোগ্রামের নমনীয়তা এবং পাঠযোগ্যতাও উন্নত করতে পারে। এটি প্রোগ্রামটিকে আরও পরিচালিত করে তোলে। কোডটি আরও ছোট টুকরো করে ভাগ করা পুনরায় ব্যবহারের জন্য বান্ধব করে তুলবে।

উদাহরণ স্বরূপ:

function curryMinus(x) 
{
  return function(y) 
  {
    return x - y;
  }
}

var minus5 = curryMinus(1);
minus5(3);
minus5(5);

আমিও করতে পারি ...

var minus7 = curryMinus(7);
minus7(3);
minus7(5);

জটিল কোড ঝরঝরে করে এবং অযৌক্তিক পদ্ধতিগুলি পরিচালনা করার জন্য এটি খুব দুর্দান্ত etc.


2

একটি ত্রিযুক্ত ফাংশন কেবল একটির পরিবর্তে একাধিক যুক্তি তালিকার জন্য প্রয়োগ করা হয়।

এখানে একটি নিয়মিত, অ-ত্রিযুক্ত ফাংশন রয়েছে যা এক্স এবং ওয়াইজের দুটি আন্ত প্যারামিটার যুক্ত করে:

scala> def plainOldSum(x: Int, y: Int) = x + y
plainOldSum: (x: Int,y: Int)Int
scala> plainOldSum(1, 2)
res4: Int = 3

এখানে ত্রিযুক্ত যে অনুরূপ ফাংশন। দুটি ইন্টার প্যারামিটারগুলির একটি তালিকার পরিবর্তে, আপনি প্রতিটি ফর্মটি প্রতিটি ইনট প্যারামিটারের দুটি তালিকায় এই ফাংশনটি প্রয়োগ করেন:

scala> def curriedSum(x: Int)(y: Int) = x + y
curriedSum: (x: Int)(y: Int)Intscala> second(2)
res6: Int = 3
scala> curriedSum(1)(2)
res5: Int = 3

এখানে যা ঘটছে তা হ'ল আপনি যখন অনুরোধ করবেন তখন আপনি curriedSumদুটি traditionalতিহ্যবাহী ফাংশন আমন্ত্রণ ফিরে ফিরে পেয়ে যাবেন। প্রথম ফাংশন অনুরোধটি নামের একটি একক আন্ত প্যারামিটার নেয় xএবং দ্বিতীয় ফাংশনের জন্য একটি ফাংশনের মান প্রদান করে। এই দ্বিতীয় ফাংশন ইন্টারঅ্যাক্টিভ প্যারামিটার নেয় y

এখানে একটি ফাংশন এখানে দেওয়া হয়েছে firstযা আত্মার মধ্যে করে যা প্রথম traditionalতিহ্যবাহী ফাংশন আমন্ত্রণটি curriedSumকরবে:

scala> def first(x: Int) = (y: Int) => x + y
first: (x: Int)(Int) => Int

প্রথম ফাংশনে 1 প্রয়োগ করা other অন্য কথায় প্রথম ফাংশনটি আহ্বান করা এবং 1-এ পাস করা দ্বিতীয় ফাংশন দেয়:

scala> val second = first(1)
second: (Int) => Int = <function1>

দ্বিতীয় ফাংশনে 2 প্রয়োগ করলে ফলাফল পাওয়া যায়:

scala> second(2)
res6: Int = 3

2

কারিং করার উদাহরণ হ'ল ফাংশনগুলি থাকার সময় আপনি কেবলমাত্র এই মুহুর্তে প্যারামিটারগুলির মধ্যে একটি জানেন:

উদাহরণ স্বরূপ:

func aFunction(str: String) {
    let callback = callback(str) // signature now is `NSData -> ()`
    performAsyncRequest(callback)
}

func callback(str: String, data: NSData) {
    // Callback code
}

func performAsyncRequest(callback: NSData -> ()) {
    // Async code that will call callback with NSData as parameter
}

এখানে, যেহেতু আপনি কলব্যাকের জন্য দ্বিতীয় প্যারামিটারটি জানেন না যখন এটি প্রেরণ করার সময় performAsyncRequest(_:)আপনাকে সেই ফাংশনে প্রেরণের জন্য অন্য একটি ল্যাম্বদা / ক্লোজার তৈরি করতে হবে।


হয় func callbackনিজেই ফিরে? এটা তোলে বলা হচ্ছে @ callback(str)তাই let callback = callback(str), কলব্যাক মাত্র ফেরত মান হয়func callback
nikk Wong

না, func callback(_:data:)দুটি প্যারামিটার গ্রহণ করে, এখানে আমি এটি কেবল একটি দিচ্ছি String, তাই এটি NSDatalet callback
পরেরটির

2

এখানে জেনেরিকের উদাহরণ এবং এন নম্বর দিয়ে ক্রিয়াকলাপের জন্য সংক্ষিপ্ততম সংস্করণ। প্যারামের।

const add = a => b => b ? add(a + b) : a; 

const add = a => b => b ? add(a + b) : a; 
console.log(add(1)(2)(3)(4)());


1

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

public static class FuncExtensions {
    public static Func<T1, Func<T2, TResult>> Curry<T1, T2, TResult>(this Func<T1, T2, TResult> func)
    {
        return x1 => x2 => func(x1, x2);
    }
}

//Usage
var add = new Func<int, int, int>((x, y) => x + y).Curry();
var func = add(1);

//Obtaining the next parameter here, calling later the func with next parameter.
//Or you can prepare some base calculations at the previous step and then
//use the result of those calculations when calling the func multiple times 
//with different input parameters.

int result = func(1);

1

ক্রিভিং জাভা স্ক্রিপ্টের উচ্চতর ক্রমের একটি।

কারিঙ হচ্ছে অনেকগুলি আর্গুমেন্টের একটি ফাংশন যা এটি পুনরায় লিখিত হয় যা এটি প্রথম যুক্তি নেয় এবং একটি ফাংশন দেয় যা ঘুরে ফিরে বাকী যুক্তি ব্যবহার করে এবং মানটি দেয় returns

বিভ্রান্ত?

একটি উদাহরণ দেখতে দিন,

function add(a,b)
    {
        return a+b;
    }
add(5,6);

এটি নিম্নলিখিত কারিং ফাংশনের অনুরূপ,

function add(a)
    {
        return function(b){
            return a+b;
        }
    }
var curryAdd = add(5);
curryAdd(6);

সুতরাং এই কোড মানে কি?

এখন আবার সংজ্ঞাটি পড়ুন,

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

এখনও বিভ্রান্ত? আমাকে গভীরভাবে ব্যাখ্যা করুন!

আপনি যখন এই ফাংশনটি কল করবেন,

var curryAdd = add(5);

এটি আপনাকে এইভাবে কোনও ফাংশন ফিরিয়ে দেবে,

curryAdd=function(y){return 5+y;}

সুতরাং, এটিকে উচ্চ-আদেশ ক্রিয়াকলাপ বলে। অর্থ, একটি ফাংশন ঘুরে দেখা অন্য ফাংশন ফেরত উচ্চতর ক্রম ফাংশন জন্য সঠিক সংজ্ঞা। এটি কিংবদন্তি, জাভা স্ক্রিপ্টের পক্ষে সবচেয়ে বড় সুবিধা। সুতরাং কারিঙে ফিরে আসুন,

এই লাইনটি কারিএড যুক্ত ফাংশনে দ্বিতীয় যুক্তিটি পাস করবে।

curryAdd(6);

যার ফলস্বরূপ,

curryAdd=function(6){return 5+6;}
// Which results in 11

আশা করি আপনি এখানে কারিঙের ব্যবহার বুঝতে পেরেছেন। সুতরাং, সুবিধার দিকে আসা,

কারি করছ কেন?

এটি কোড পুনরায় ব্যবহারযোগ্যতার ব্যবহার করে। কম কোড, কম ত্রুটি। আপনি জিজ্ঞাসা করতে পারেন এটি কম কোডটি কীভাবে?

আমি এটি ইসএমএ স্ক্রিপ্ট 6 টি নতুন বৈশিষ্ট্যযুক্ত তীর ফাংশন দিয়ে প্রমাণ করতে পারি।

হ্যাঁ! ইসিএমএ 6, আমাদের তীর ফাংশন নামে একটি দুর্দান্ত বৈশিষ্ট্য সরবরাহ করুন,

function add(a)
    {
        return function(b){
            return a+b;
        }
    }

তীর ফাংশনটির সাহায্যে আমরা উপরের ফাংশনটি নিম্নরূপ লিখতে পারি,

x=>y=>x+y

ঠিক আছে তো?

সুতরাং, কম কোড এবং কম বাগগুলি !!

এই উচ্চ-অর্ডার ক্রিয়াকলাপের সাহায্যে সহজেই কোনও বাগ-মুক্ত কোড বিকাশ করা যায়।

আমি তোমাকে চ্যালেঞ্জ করছি!

আশা করি, আপনি বুঝতে পেরেছেন কি কারি হচ্ছে। আপনার যদি কোনও ব্যাখ্যা প্রয়োজন হয় তবে দয়া করে এখানে বিনা দ্বিধায় মন্তব্য করুন।

ধন্যবাদ একটি সুন্দর দিন আছে!


0

"কারজিং ইন রিজনেল এমএমএল" এর একটি উদাহরণ রয়েছে।

let run = () => {
    Js.log("Curryed function: ");
    let sum = (x, y) => x + y;
    Printf.printf("sum(2, 3) : %d\n", sum(2, 3));
    let per2 = sum(2);
    Printf.printf("per2(3) : %d\n", per2(3));
  };
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.