তরকারী এবং আংশিক প্রয়োগের মধ্যে পার্থক্য কি?


438

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

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

কেউ কি আমাকে উভয় পদের সংজ্ঞা এবং কীভাবে তাদের পার্থক্য রয়েছে তার বিশদ সরবরাহ করতে পারেন?

উত্তর:


256

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

function f(x,y,z) { z(x(y));}

তরকারী হয়ে গেলে, হয়ে যায়:

function f(x) { lambda(y) { lambda(z) { z(x(y)); } } }

F (x, y, z) এর সম্পূর্ণ অ্যাপ্লিকেশন পেতে, আপনাকে এটি করতে হবে:

f(x)(y)(z);

অনেক কার্যকরী ভাষা আপনাকে লিখতে দেয় f x y z। যদি আপনি কেবল কল করেন f x yবা f (x) (y) হন তবে আপনি একটি আংশিক প্রয়োগিত ফাংশন পাবেন — রিটার্ন মানটি lambda(z){z(x(y))}x এবং y এর মানগুলির সাথে উত্তীর্ণ হওয়া বন্ধ হওয়া f(x,y)

আংশিক অ্যাপ্লিকেশনটি ব্যবহার করার একটি উপায় হ'ল ভাঁজের মতো সাধারণ ক্রিয়াকলাপগুলির আংশিক অ্যাপ্লিকেশন হিসাবে ফাংশনগুলি সংজ্ঞায়িত করা :

function fold(combineFunction, accumulator, list) {/* ... */}
function sum     = curry(fold)(lambda(accum,e){e+accum}))(0);
function length  = curry(fold)(lambda(accum,_){1+accum})(empty-list);
function reverse = curry(fold)(lambda(accum,e){concat(e,accum)})(empty-list);

/* ... */
@list = [1, 2, 3, 4]
sum(list) //returns 10
@f = fold(lambda(accum,e){e+accum}) //f = lambda(accumulator,list) {/*...*/}
f(0,list) //returns 10
@g = f(0) //same as sum
g(list)  //returns 10

40
আপনি বলছেন যে আপনি যখন কোনও ফাংশনটি কারি করেন এবং কিছু ব্যবহার করেন, তবে ফলস্বরূপ সমস্ত কার্যকারিতা নয়?
চামচমিজার

9
কম বা কম, হ্যাঁ আপনি যদি কেবলমাত্র আর্গুমেন্টের সাবসেট সরবরাহ করেন তবে আপনি এমন একটি ফাংশন ফিরে পাবেন যা বাকী আর্গুমেন্টগুলি গ্রহণ করে
মার্ক সিডাড

1
কোন ফাংশন f (a, b, c, d) কে g (a, b) এ আংশিক প্রয়োগ হিসাবে গণনা করবে? বা এটি শুধুমাত্র ত্রিযুক্ত ফাংশনগুলিতে প্রয়োগ করা হয়? ব্যথা হওয়ার জন্য দুঃখিত, তবে আমি এখানে একটি সুস্পষ্ট উত্তরের জন্য কৌতুক করছি।
চামচমিজার

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

5
@JasonBunting, আপনার প্রথম মন্তব্য, কী খবর? কথা বলা হয়েছে সংক্রান্ত decurrying । কারিঙ ইনপুট হিসাবে একটি বহু-আরগ ফাংশন নিচ্ছে এবং আউটপুট হিসাবে 1-আরগ ফাংশনের একটি শৃঙ্খলা ফিরিয়ে দিচ্ছে। ডি-কারিঙ ইনপুট হিসাবে 1-আরগ ফাংশনের একটি শৃঙ্খল নিচ্ছে এবং আউটপুট হিসাবে বহু-আরগ ফাংশনটি ফিরিয়ে দিচ্ছে। উপর বিস্তারিত হিসাবে stackoverflow.com/a/23438430/632951
Pacerier

165

তারা কীভাবে পৃথক হয় তা দেখার সহজ উপায় হ'ল আসল উদাহরণ বিবেচনা করা । ধরা যাক আমাদের একটি ফাংশন আছে Addযা ইনপুট হিসাবে 2 নম্বর নেয় এবং একটি সংখ্যা আউটপুট হিসাবে প্রদান করে, যেমন Add(7, 5)রিটার্ন 12। এক্ষেত্রে:

  • আংশিকভাবেAdd একটি মান সহ ফাংশন প্রয়োগ করা7 আমাদের আউটপুট হিসাবে একটি নতুন ফাংশন দেবে। এই ফাংশনটি নিজেই ইনপুট হিসাবে 1 নম্বর নেয় এবং একটি সংখ্যা আউটপুট করে। যেমন:

    Partial(Add, 7); // returns a function f2 as output
    
                     // f2 takes 1 number as input and returns a number as output
    

    সুতরাং আমরা এটি করতে পারি:

    f2 = Partial(Add, 7);
    f2(5); // returns 12;
           // f2(7)(5) is just a syntactic shortcut
    
  • ফাংশনটি কারি করাAdd আমাদের আউটপুট হিসাবে একটি নতুন ফাংশন দেবে। যে ফাংশন নিজেই ইনপুট এবং আউটপুট হিসাবে 1 টি সংখ্যা লাগে এখনো একটি নতুন ফাংশন। তৃতীয় ফাংশনটি তখন ইনপুট হিসাবে 1 নম্বর নেয় এবং একটি সংখ্যা আউটপুট হিসাবে দেয়। যেমন:

    Curry(Add); // returns a function f2 as output
    
                // f2 takes 1 number as input and returns a function f3 as output
                // i.e. f2(number) = f3
    
                // f3 takes 1 number as input and returns a number as output
                // i.e. f3(number) = number
    

    সুতরাং আমরা এটি করতে পারি:

    f2 = Curry(Add);
    f3 = f2(7);
    f3(5); // returns 12
    

অন্য কথায়, "তরকারী" এবং "আংশিক প্রয়োগ" দুটি সম্পূর্ণ ভিন্ন ফাংশন। কারিঙে ঠিক 1 ইনপুট লাগে, তবে আংশিক প্রয়োগে 2 (বা আরও বেশি) ইনপুট লাগে।

যদিও তারা উভয়ই ফাংশনটিকে আউটপুট হিসাবে ফেরত দেয়, উপরে ফিরে প্রদর্শিত হিসাবে ফাংশনগুলি সম্পূর্ণ ভিন্ন রূপের হয়।


24
আংশিক অ্যাপ্লিকেশন থেকে একটি ফাংশন রূপান্তরিত n-aryকরার (x - n)-aryথেকে সংবাহন, n-aryকরতে n * 1-ary। আংশিক প্রয়োগিত ফাংশনটির একটি হ্রাস (আবেদনের) সুযোগ থাকে , যা এর Add7চেয়ে কম ভাবের হয় Add। অন্যদিকে একটি ত্রিযুক্ত ফাংশন মূল ফাংশনের মতোই অভিব্যক্তিপূর্ণ।
বব

4
আমি বিশ্বাস করি যে যখন আমরা f (x, y, z) => আর কারি করি তখন আরও f (x) পাই যা আমরা g (y) => h (z) => আর, একেকটি যুক্তি গ্রহন করে; তবে যখন আমরা f (x, y, z) কে f (x) হিসাবে আংশিকভাবে প্রয়োগ করি তখন আমরা g (y, z) => আর পাই, যা দুটি যুক্তি সহ। যদি সেই বৈশিষ্ট্যের জন্য না হয় তবে আমরা বলতে পারি যে কারিরিং 0 টি আর্গুমেন্টের আংশিক প্রয়োগের মতো, এইভাবে সমস্ত আর্গুমেন্টকে সীমাহীন রেখে দেওয়া; তবে বাস্তবে চ () 0 টি আর্গুমেন্টে আংশিক প্রয়োগ হ'ল একটি ফাংশন যা একবারে 3 টি আর্গ ব্যবহার করে, ত্রিযুক্ত চ () এর বিপরীতে।
মাকসিম গুমেরভ

2
আবারও সঠিক উত্তরটি প্রথম বা সর্বাধিক ভোট দেওয়া হয়নি: এই উত্তরটির শেষে কারি বনাম আংশিকের স্বাক্ষরের সহজ ব্যাখ্যাটি প্রশ্নটি সমাধান করার পক্ষে সত্যই সহজ উপায়।
fnl

2
মন্তব্যটির f2(7)(5) is just a syntactic shortcutঅর্থ কী? (আমি খুব কম জানি)) f2ইতিমধ্যে "7" সম্পর্কে / জেনে নেই?
Zach Mierzejewski

@ পেসারিয়ার, curryকোথাও কোনও বাস্তবায়ন রয়েছে (এটি মনে হয় না functools)
অ্যালাঙ্কালভিটি

51

দ্রষ্টব্য: এফ # বেসিক্স থেকে। নেট বিকাশকারীদের কার্যকরী প্রোগ্রামিংয়ে যাওয়ার জন্য একটি দুর্দান্ত প্রারম্ভিক নিবন্ধ থেকে নেওয়া হয়েছিল ।

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

let multiply x y = x * y    
let double = multiply 2
let ten = double 5

এখনই, আপনার এমন আচরণ দেখা উচিত যা বেশিরভাগ অপরিহার্য ভাষাগুলির থেকে আলাদা। দ্বিতীয় বিবৃতিটি একটি ফাংশনে দুটি গ্রহণ করে একটি যুক্তি পাস করে ডাবল নামে একটি নতুন ফাংশন তৈরি করে। ফলাফলটি এমন একটি ফাংশন যা একটি অন্তর্নির্মিত আর্গুমেন্ট গ্রহণ করে এবং একই আউটপুট দেয় যেমন আপনি x এর সাথে 2 এবং y এর সাথে সমান হিসাবে আর্গুমেন্ট বলেছিলেন multip আচরণের ক্ষেত্রে, এটি এই কোডের মতোই:

let double2 z = multiply 2 z

প্রায়শই লোকেরা ভুল করে বলে যে গুণটি ডাবল গঠনে প্রস্তুত ried তবে এটি কেবল কিছুটা সত্য। গুণিত ফাংশনটি ত্রিযুক্ত হয়, তবে এটি সংজ্ঞায়িত হলেই ঘটে কারণ এফ # এ ফাংশনগুলি ডিফল্টরূপে কারিড হয়। যখন ডাবল ফাংশনটি তৈরি করা হয়, তখন এটি আরও সঠিকভাবে বলা যায় যে বহুগুণ ফাংশনটি আংশিকভাবে প্রয়োগ করা হয়েছে।

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

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


33

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

আরেকটি দরকারী-সন্ধানী পৃষ্ঠা (যা আমি স্বীকার করি যে আমি এখনও পুরোপুরি পড়িনি) হ'ল "কার্ভিং এবং আংশিক অ্যাপ্লিকেশন সহ জাভা ক্লোজার"

দেখে মনে হচ্ছে এটি বিস্তৃত-বিভ্রান্তিকর পদগুলির জুটি, মনে রাখবেন।


5
প্রথম লিঙ্কটি পার্থক্য সম্পর্কে স্পট অন হয়। আমি এখানে আরও একটি দরকারী পেয়েছি: বিট.লি
জেসন

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

9
আপনার পোস্ট করা জোন লিঙ্কগুলি তথ্যবহুল, তবে আপনার উত্তরটি প্রসারিত করা এবং এখানে আরও কিছু তথ্য যুক্ত করা ভাল।
জহির আহমেদ

2
@ জন মেটা.স্ট্যাকওভারফ্লো. com
জিজ্ঞাসা /

11
কোনও দম্পতির লিঙ্ক এবং একটি ভর্তির জন্য আপনি 20 টি upvotes পেয়েছেন তা বিশ্বাস করতে পারি না আপনি তরকারী এবং আংশিক প্রয়োগের মধ্যে পার্থক্যটি সত্যই জানেন না। ভাল খেলেছে স্যার।
AlienWebguy

16

আমি এর উত্তরটি অন্য থ্রেডে https://stackoverflow.com/a/12846865/1685865 এ দিয়েছি । সংক্ষেপে, আংশিক ফাংশন অ্যাপ্লিকেশনটি কম আর্গুমেন্টের সাথে অন্য ক্রিয়াকলাপের জন্য প্রদত্ত মাল্টিভারিয়াল ফাংশনের কিছু আর্গুমেন্টগুলি ঠিক করার বিষয়ে, যখন কারিং এন আর্গুমেন্টের কোনও ক্রিয়াকলাপকে একটি আনরি ফাংশনে পরিণত করার বিষয়ে যা একটি অবিচ্ছিন্ন ফাংশন প্রদান করে ... [একটি উদাহরণ কার্পিং এই পোস্টের শেষে দেখানো হয়েছে।]

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

(তরকারীকরণের উদাহরণ)

অনুশীলনে একটি শুধু লিখতে হবে না

lambda x: lambda y: lambda z: x + y + z

বা সমতুল্য জাভাস্ক্রিপ্ট

function (x) { return function (y){ return function (z){ return x + y + z }}}

পরিবর্তে

lambda x, y, z: x + y + z

কারিঙের খাতিরে


1
আপনি কি বলবেন যে তড়িৎ তড়িৎ প্রয়োগের একটি নির্দিষ্ট ক্ষেত্রে?
চামচমাইজার

1
@ স্পুনমিজার, না, কারি আংশিক প্রয়োগের নির্দিষ্ট ক্ষেত্রে নয়: একটি 2-ইনপুট ফাংশনের আংশিক প্রয়োগ ফাংশনটি কারি করার মতো নয়। স্ট্যাকওভারফ্লো . com/a/23438430/632951 দেখুন ।
পেসারিয়ার

10

সংবাহন একটি ফাংশন এক যুক্তি যা একটি ফাংশন লাগে fএবং একটি নতুন ফাংশনটি h। দ্রষ্টব্য এটি hথেকে একটি আর্গুমেন্ট গ্রহণ করে Xএবং এমন ফাংশন প্রদান করে যা মানচিত্র Yকরে Z:

curry(f) = h 
f: (X x Y) -> Z 
h: X -> (Y -> Z)

আংশিক অ্যাপ্লিকেশন হ'ল দুটি (বা আরও) আর্গুমেন্টগুলির একটি ফাংশন যা একটি ফাংশন নেয় fএবং এক বা একাধিক অতিরিক্ত আর্গুমেন্ট fনতুন ফাংশনে ফিরে আসে g:

part(f, 2) = g
f: (X x Y) -> Z 
g: Y -> Z

বিভ্রান্তি দেখা দেয় কারণ একটি দ্বি-যুক্তির ক্রিয়াকলাপের সাথে নিম্নলিখিত সমতাটি ধারণ করে:

partial(f, a) = curry(f)(a)

উভয় পক্ষই একই এক-যুক্তি ফাংশন দেবে।

উচ্চতর আরেটি ফাংশনের জন্য সমতাটি সত্য নয় কারণ এক্ষেত্রে কারি করানো একটি যুক্তিযুক্ত ফাংশনটি ফিরিয়ে দেবে, অন্যদিকে আংশিক প্রয়োগটি একাধিক-যুক্তি ফাংশন ফিরিয়ে দেবে।

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

সূত্র: উইকিপিডিয়া কারিঙ


8

কারি এবং আংশিক প্রয়োগের মধ্যে পার্থক্যটি নিম্নলিখিত নীচের জাভাস্ক্রিপ্ট উদাহরণের মাধ্যমে সেরা চিত্রিত করা যেতে পারে:

function f(x, y, z) {
    return x + y + z;
}

var partial = f.bind(null, 1);

6 === partial(2, 3);

আংশিক প্রয়োগের ফলে ছোট আধ্যাত্মিক ক্রিয়া ঘটে; উপরের উদাহরণে, fএর আরটিটি 3 রয়েছে এবং partialকেবলমাত্র 2 এর আধ্যাত্মিকতা রয়েছে আরও গুরুত্বপূর্ণ বিষয়, একটি আংশিক প্রয়োগ ফাংশনটি অনুরোধ করা হওয়ার সাথে সাথে ফলাফলটি সরাসরি ফিরিয়ে আনবে , কারিং শৃঙ্খলের নিচে অন্য কোনও ফাংশন নয়। সুতরাং আপনি যদি এরকম কিছু দেখতে partial(2)(3)পান তবে বাস্তবে এটি আংশিক প্রয়োগ নয়।

আরও পড়া:


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

6

সহজ উত্তর

কারি: আপনাকে কোনও ফাংশনে কল করতে দেয়, একাধিক কলে বিভক্ত করে প্রতি কল-এর জন্য একটি যুক্তি সরবরাহ করে।

আংশিক: আপনাকে কোনও ফাংশনে কল করতে দেয়, একাধিক কলে বিভক্ত করে, প্রতি কলটিতে একাধিক যুক্তি সরবরাহ করে।


সাধারণ ইঙ্গিত

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

ফাংশনটিতে 2 টিরও বেশি আর্গুমেন্ট থাকলে আসল পার্থক্যটি দেখা যায়।


সাধারণ ই (সি) (নমুনা)

(জাভাস্ক্রিপ্টে)

function process(context, success_callback, error_callback, subject) {...}

প্রসঙ্গে এবং কলব্যাকের মতো যুক্তিগুলি কেন সর্বদা পাস করা, যদি তারা সবসময় একই থাকে? ফাংশনটির জন্য কিছু মান আবদ্ধ করুন

processSubject = _.partial(process, my_context, my_success, my_error)

এবং এর সেটিতে কল subject1 এবং FOOBAR সঙ্গে

processSubject('subject1');
processSubject('foobar');

স্বাচ্ছন্দ্য, তাই না? 😉

সঙ্গে সংবাহন সময় প্রতি এক যুক্তি পাস প্রয়োজন চাই

curriedProcess = _.curry(process);
processWithBoundedContext = curriedProcess(my_context);
processWithCallbacks = processWithBoundedContext(my_success)(my_error); // note: these are two sequential calls

result1 = processWithCallbacks('subject1');
// same as: process(my_context, my_success, my_error, 'subject1');
result2 = processWithCallbacks('foobar'); 
// same as: process(my_context, my_success, my_error, 'foobar');

দাবি পরিত্যাগী

আমি সমস্ত একাডেমিক / গাণিতিক ব্যাখ্যা এড়িয়ে গেছি। কারণ আমি এটা জানি না। হতে পারে এটি সাহায্য করেছে 🙃


4

শেখার সময় আমার এই প্রশ্নটি অনেক ছিল এবং তখন থেকে এটি বহুবার জিজ্ঞাসা করা হয়েছিল। আমি পার্থক্যটি বর্ণনা করার সবচেয়ে সহজ উপায়টি হ'ল উভয়ই এক রকম :) আমাকে ব্যাখ্যা করতে দাও ... স্পষ্টতই পার্থক্য রয়েছে।

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

add = (x, y) => x + y

যদি আমি একটি "অ্যাডঅন" ফাংশন চাইতাম, তবে আমি আংশিকভাবে এটি প্রয়োগ করতে পারি বা এটি কারি করতাম:

addOneC = curry(add, 1)
addOneP = partial(add, 1)

এখন তাদের ব্যবহার স্পষ্ট:

addOneC(2) #=> 3
addOneP(2) #=> 3

তাহলে পার্থক্য কী? ঠিক আছে, এটি সূক্ষ্ম, তবে আংশিক প্রয়োগের সাথে কিছু যুক্তি সরবরাহ করা জরুরী এবং ফিরে ফাংশনটি পরবর্তী অনুরোধের পরে মূল ফাংশনটি সম্পাদন করবে যেখানে কারি করানো সমস্ত আর্গুমেন্ট প্রয়োজনীয় না হওয়া পর্যন্ত অপেক্ষা করতে থাকবে:

curriedAdd = curry(add) # notice, no args are provided
addOne = curriedAdd(1) # returns a function that can be used to provide the last argument
addOne(2) #=> returns 3, as we want

partialAdd = partial(add) # no args provided, but this still returns a function
addOne = partialAdd(1) # oops! can only use a partially applied function once, so now we're trying to add one to an undefined value (no second argument), and we get an error

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

curriedAdd = curry(add)
curriedAdd()()()()()(1)(2) # ugly and dumb, but it works

partialAdd = partial(add)
partialAdd()()()()()(1)(2) # second invocation of those 7 calls fires it off with undefined parameters

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

আপডেট: কিছু ভাষা বা লিবি বাস্তবায়ন আপনাকে আংশিক প্রয়োগের বাস্তবায়নের (চূড়ান্ত মূল্যায়নের মোট যুক্তিগুলির সংখ্যা) পাস করার অনুমতি দেবে যা আমার দুটি বিবরণকে একটি বিভ্রান্তিকর গোলযোগের সাথে আবদ্ধ করতে পারে ... তবে এই মুহূর্তে দুটি কৌশল হ'ল মূলত বিনিময়যোগ্য


3

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

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


3

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

# partial application
partial_apply = (func) ->
  args = [].slice.call arguments, 1
  -> func.apply null, args.concat [].slice.call arguments

sum_variadic = -> [].reduce.call arguments, (acc, num) -> acc + num

add_to_7_and_5 = partial_apply sum_variadic, 7, 5

add_to_7_and_5 10 # returns 22
add_to_7_and_5 10, 11, 12 # returns 45

# currying
curry = (func) ->
  num_args = func.length
  helper = (prev) ->
    ->
      args = prev.concat [].slice.call arguments
      return if args.length < num_args then helper args else func.apply null, args
  helper []

sum_of_three = (x, y, z) -> x + y + z
curried_sum_of_three = curry sum_of_three
curried_sum_of_three 4 # returns a function expecting more arguments
curried_sum_of_three(4)(5) # still returns a function expecting more arguments
curried_sum_of_three(4)(5)(6) # returns 15
curried_sum_of_three 4, 5, 6 # returns 15

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

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


2

আমি ধরে নিচ্ছি যে বেশিরভাগ লোকেরা যারা এই প্রশ্নটি জিজ্ঞাসা করছে তারা ইতিমধ্যে প্রাথমিক ধারণাগুলির সাথে পরিচিত তাই তাদের এ বিষয়ে কথা বলার দরকার নেই। এটি ওভারল্যাপ যা বিভ্রান্তিকর অংশ।

আপনি ধারণাগুলি সম্পূর্ণরূপে ব্যবহার করতে সক্ষম হতে পারেন, তবে আপনি এগুলি ছদ্ম-পারমাণবিক নিরাকার ধারণা ধারণার ঝাপসা হিসাবে একসাথে বুঝতে পারেন। কী অনুপস্থিত তা জেনে রাখা হচ্ছে যে তাদের মধ্যে সীমানাটি কোথায়।

প্রত্যেকটি কী তা ব্যাখ্যা করার পরিবর্তে কেবল তাদের পার্থক্য - সীমানা হাইলাইট করা সহজ।

কারিটিং হ'ল আপনি যখন ফাংশনটি সংজ্ঞায়িত করেন।

আপনি যখন ফাংশনটি কল করেন তখন আংশিক অ্যাপ্লিকেশন হয় ।

একটি ফাংশন কল করার জন্য অ্যাপ্লিকেশনটি গণিত-স্পোক।

আংশিক অ্যাপ্লিকেশনটির জন্য একটি তরকারী ফাংশন কল করা এবং রিটার্নের ধরণ হিসাবে কোনও ফাংশন পাওয়া দরকার।


1

এখানে আরও দুর্দান্ত উত্তর রয়েছে তবে আমি বিশ্বাস করি জাভাতে এই উদাহরণটি (আমার বোঝাপড়া অনুসারে) কিছু লোকের পক্ষে উপকারী হতে পারে:

public static <A,B,X> Function< B, X > partiallyApply( BiFunction< A, B, X > aBiFunction, A aValue ){
    return b -> aBiFunction.apply( aValue, b );
}

public static <A,X> Supplier< X > partiallyApply( Function< A, X > aFunction, A aValue ){
    return () -> aFunction.apply( aValue );
}

public static <A,B,X> Function<  A, Function< B, X >  > curry( BiFunction< A, B, X > bif ){
    return a -> partiallyApply( bif, a );
}

সুতরাং কার্বিং আপনাকে ফাংশন তৈরি করতে একটি তর্ক-যুক্ত ফাংশন দেয় যেখানে আংশিক-প্রয়োগটি একটি মোড়ক ফাংশন তৈরি করে যা হার্ডড এক বা একাধিক আর্গুমেন্টকে কোড করে।

আপনি যদি অনুলিপি এবং পেস্ট করতে চান তবে ধরণগুলি আরও নিভৃত হওয়ায় কাজ করার জন্য নীচেরটি হৈচৈপূর্ণ তবে বন্ধুত্বপূর্ণ:

public static <A,B,X> Function< ? super B, ? extends X > partiallyApply( final BiFunction< ? super A, ? super B, X > aBiFunction, final A aValue ){
    return b -> aBiFunction.apply( aValue, b );
}

public static <A,X> Supplier< ? extends X > partiallyApply( final Function< ? super A, X > aFunction, final A aValue ){
    return () -> aFunction.apply( aValue );
}

public static <A,B,X> Function<  ? super A,  Function< ? super B, ? extends X >  > curry( final BiFunction< ? super A, ? super B, ? extends X > bif ){
    return a -> partiallyApply( bif, a );
}

নিম্নলিখিতটি আমাকে মূল অন্তর্দৃষ্টি দিয়েছে: "সুতরাং তরকারীকরণ আপনাকে ফাংশন তৈরি করতে একটি যুক্তিযুক্ত ফাংশন দেয় যেখানে আংশিক-প্রয়োগটি একটি মোড়ক ফাংশন তৈরি করে যা হার্ডড এক বা একাধিক আর্গুমেন্টকে কোড করে।"
রোল্যান্ড

0

এটি লেখার সময়, আমি তরকারী এবং উদ্রেককারী গুলিয়ে ফেলেছিলাম। এগুলি ফাংশনে বিপরীত রূপান্তর are আপনি যাকে কল করেন তা আসলেই গুরুত্বপূর্ণ নয়, যতক্ষণ আপনি রূপান্তর এবং এর বিপরীতটি প্রতিনিধিত্ব করেন what

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

(+) :: Int -> Int -> Int

এখন, আপনি কীভাবে এটি একটি ফাংশনে রূপান্তর করবেন যা একক যুক্তি গ্রহণ করে? আপনি অবশ্যই প্রতারণা করুন!

plus :: (Int, Int) -> Int

লক্ষ্য করুন যে প্লাসটি এখন একটি একক যুক্তি নেয় (এটি দুটি জিনিস নিয়ে গঠিত)। সুপার!

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

(uncurry (+)) (1,2)

সুতরাং আংশিক ফাংশন অ্যাপ্লিকেশন কি? দুটি আর্গুমেন্টে কোনও ক্রিয়াকলাপকে একটি যুক্তি দিয়ে ফাংশনে রূপান্তর করা আলাদা উপায়। যদিও এটি ভিন্নভাবে কাজ করে। আবার, উদাহরণস্বরূপ (+) নেওয়া যাক। আমরা কীভাবে এটিকে এমন একটি ফাংশনে পরিণত করতে পারি যা একটি যুক্তি হিসাবে একটি একক অন্তর্ গ্রহণ করে? আমরা ঠকাই!

((+) 0) :: Int -> Int

এটি যে ফাংশনটি কোনও অন্তর্গত শূন্য যোগ করে।

((+) 1) :: Int -> Int

যে কোনও ইন্টিতে 1 যুক্ত করে। ইত্যাদি। এর প্রতিটি ক্ষেত্রে (+) "আংশিকভাবে প্রয়োগ" হয়।

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