একইসাথে কারিরিং এবং বৈকল্পিক ফাংশন রাখা কি সম্ভব?


13

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

এখানে কিছু সিউডোকোড রয়েছে:

sum = if @args.empty then 0 else @args.head + sum @args.tail

যা এর সমস্ত যুক্তি যোগ করতে পারে বলে মনে করা হচ্ছে। তারপরে, যদি sumনিজেই একটি সংখ্যার সাথে চিকিত্সা করা হয়, তবে ফলাফল হয় 0। উদাহরণ স্বরূপ,

sum + 1

1 এর সমান, ধরে নিলে এটি +কেবল সংখ্যায় কাজ করতে পারে। যাইহোক, এমনকি sum == 0সত্য, sumতবুও তার মান এবং কার্যকরী সম্পত্তি বজায় রাখবে যতক্ষণ না আর্গুমেন্ট দেওয়া হয় (তাই "আংশিকভাবে প্রয়োগ" এবং একই সাথে "ভেরেনডিক" একই সাথে), উদাহরণস্বরূপ, যদি আমি ঘোষণা করি

g = sum 1 2 3

এর gসমান 6, তবে আমরা আরও আবেদন করতে পারি g। উদাহরণস্বরূপ, g 4 5 == 15সত্য। এই ক্ষেত্রে, আমরা বস্তুটিকে gআক্ষরিক দ্বারা প্রতিস্থাপন করতে পারি না 6, যদিও পূর্ণসংখ্যার হিসাবে বিবেচনা করার সময় এগুলি একই মান দেয় তবে তাদের ভিতরে বিভিন্ন কোড থাকে।

যদি এই নকশাটি সত্যিকারের প্রোগ্রামিং ভাষায় ব্যবহৃত হয়, তবে তা কোনও বিভ্রান্তি বা দ্বিধাদ্বন্দ্ব সৃষ্টি করবে?


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

তারপরে আমার প্রশ্নটি সরল করা হয়েছে "একই সাথে কোনও জিনিস কোনও ফাংশন এবং একটি অ-ফাংশন মান হতে পারে?" উপরের উদাহরণে, sumহয় 0একটি আর্গুমেন্ট ছাড়া যাও recursively একটি আর্গুমেন্ট নিজেই কল।
মাইকেল স্যাং

এটা কি কাজ নয় reduce?
র‌্যাচেট ফ্রিক

1
ফাংশন আপনার উপর ব্যবহার করছেন কটাক্ষপাত args: empty, head, এবং tail। এগুলি সমস্ত তালিকার ফাংশন, যা সম্ভবতঃ আরও সহজ ও সহজবোধ্য জিনিস হ'ল তালিকা ব্যবহার করা হবে যেখানে ভ্যারিয়েডিক স্টাফগুলি থাকবে suggest (সুতরাং, sum [1, 2, 3]পরিবর্তে sum 1 2 3)
মাইকেল শ '

উত্তর:


6

কিভাবে varargs বাস্তবায়ন করা যেতে পারে? যুক্তি তালিকার শেষের সিগন্যাল করার জন্য আমাদের কিছু ব্যবস্থা দরকার। এটি হয় হতে পারে

  • একটি বিশেষ টার্মিনেটর মান, বা
  • অতিরিক্ত প্যারামিটার হিসাবে ভারাক তালিকার দৈর্ঘ্য অতিক্রম করেছে।

এই দুটি পদ্ধতিই ভারার্গগুলি বাস্তবায়নের জন্য কারিঙের প্রসঙ্গে ব্যবহার করা যেতে পারে তবে সঠিক টাইপিং একটি বড় সমস্যা হয়ে দাঁড়িয়েছে। আসুন ধরে নেওয়া যাক আমরা কোনও ফাংশন নিয়ে কাজ করছি sum: ...int -> int, এই ফাংশনটি কারিরিং ব্যবহার করে (সুতরাং আমাদের কাছে আসলে আরও একটি ধরণের রয়েছে sum: int -> ... -> int -> int, কেবলমাত্র আমরা আর্গুমেন্টের সংখ্যা জানি না তা বাদ দিয়ে)।

কেস: টার্মিনেটর মান: আসুন endবিশেষ টার্মিনেটর এবং Tএর ধরণ থাকুক sum। এখন আমরা জানি যে প্রয়োগ endফাংশন আয়: sum: end -> int, এবং যে কোন int প্রয়োগ আমরা অন্য সমষ্টি মত ফাংশন পাবেন: sum: int -> T। অতএব Tএই ধরনের ইউনিয়ন হল: T = (end -> int) | (int -> T)। দ্বারা substituting T, আমরা যেমন বিভিন্ন সম্ভব ধরনের পেতে end -> int, int -> end -> int, int -> int -> end -> int, ইত্যাদি তবে, অধিকাংশ টাইপ সিস্টেম এ ধরনের মিটমাট না।

কেস: সুস্পষ্ট দৈর্ঘ্য: একটি ভারার্গ ফাংশনের প্রথম যুক্তি হ'ল ভারার্গের সংখ্যা। সুতরাং sum 0 : int, sum 1 : int -> int, sum 3 : int -> int -> int -> intইত্যাদি এই কিছু টাইপ সিস্টেম সমর্থিত এবং একটি উদাহরণ হয় নির্ভরশীল টাইপিং । - আসলে, আর্গুমেন্টের সংখ্যা একটি টাইপ প্যারামিটার এবং একটি নিয়মিত প্যারামিটার হবে এটা ফাংশনের arity একটি রানটাইম মান উপর নির্ভর করে জন্য জানার জন্য না, s = ((sum (floor (rand 3))) 1) 2করতে হয় আপনি এই মূল্যায়ণ: স্পষ্টত অসুস্থ টাইপ হয় s = ((sum 0) 1) 2 = (0 1) 2, s = ((sum 1) 1) 2 = 1 2অথবা s = ((sum 2) 1) 2 = 3

অনুশীলনে, এই কৌশলগুলির কোনওটি ব্যবহার করা উচিত নয় কারণ সেগুলি ত্রুটি-ঝুঁকির কারণ এবং সাধারণ ধরণের সিস্টেমে কোনও (অর্থপূর্ণ) প্রকার নেই। পরিবর্তে, মাত্র এক প্যারামিটারের যেমন মান একটি তালিকা পাস: sum: [int] -> int

হ্যাঁ, কোনও বস্তুর পক্ষে একটি ফাংশন এবং মান উভয়ই প্রদর্শিত হওয়া সম্ভব, যেমন জবরদস্তি সহ একটি টাইপ সিস্টেমে। আসুন sumএকটি হতে দিন SumObj, যার দুটি জবর রয়েছে:

  • coerce: SumObj -> int -> SumObjsumএকটি ফাংশন হিসাবে ব্যবহার করার অনুমতি দেয় , এবং
  • coerce: SumObj -> int আমাদের ফলাফল নিষ্কাশন করতে দেয়।

প্রযুক্তিগতভাবে, এটি উপরের টার্মিনেটর মান ক্ষেত্রে একটি প্রকরণ, সহ T = SumObjএবং coerceএই ধরণের জন্য একটি মোড়ক মোড়ক হওয়া। অনেকগুলি অবজেক্ট-ভিত্তিক ভাষায়, এটি অপারেটর ওভারলোডিংয়ের সাথে তুচ্ছভাবে প্রয়োগযোগ্য, যেমন সি ++:

#include <iostream>
using namespace std;

class sum {
  int value;
public:
  explicit sum() : sum(0) {}
  explicit sum(int x) : value(x) {}
  sum operator()(int x) const { return sum(value + x); }  // function call overload
  operator int() const { return value; } // integer cast overload
};

int main() {
  int zero = sum();
  cout << "zero sum as int: " << zero << '\n';
  int someSum = sum(1)(2)(4);
  cout << "some sum as int: " << someSum << '\n';
}

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

আপনি আপনার নিজের উচ্চতর অর্ডার ফাংশনটি তৈরি করতে পারেন যা কোনও তালিকার মতো কোনও ফাংশন প্রয়োগ করে যা আংশিকভাবে প্রয়োগ করে curryList : ([a] -> b) -> [a] -> [a] -> b, curryList f xs ys = f (xs ++ ys)
জ্যাক

2

এটি কীভাবে কাজ করে তার বর্ণনা সহ আপনি হাস্কেল-এ প্রিন্টফের এই বাস্তবায়নটি দেখতে চাইতে পারেন । এই ধরণের কাজ করার বিষয়ে ওলেগ কিসিলিভের কাগজের পরবর্তী পৃষ্ঠায় একটি লিঙ্ক রয়েছে, যা পড়াও মূল্যবান। আসলে, আপনি যদি একটি কার্যকরী ভাষা ডিজাইন করেন তবে ওলেগের ওয়েবসাইটটি সম্ভবত বাধ্যতামূলক পড়া উচিত।

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

type SumType = (t : union{Int,Null}) -> {SumType, if t is Int|
                                         Int,     if t is Null}
sum :: SumType
sum (v : Int) = v + sum
sum (v : Null) = 0

একটি সুস্পষ্ট নাম না দিয়ে পুনরাবৃত্ত প্রকারের সংজ্ঞা দেওয়ার জন্য একটি বিমূর্ততা এই জাতীয় ফাংশনগুলি লেখার পক্ষে সহজ করে তুলতে পারে।

সম্পাদনা করুন: অবশ্যই আমি আবার প্রশ্নটি পড়েছি এবং আপনি একটি গতিশীল টাইপড ভাষা বলেছিলেন , যেখানে স্পষ্টতই টাইপ মেকানিক্সটি প্রাসঙ্গিক নয় এবং তাই @ অ্যামনের উত্তরে সম্ভবত আপনার প্রয়োজনীয় সমস্ত কিছুই রয়েছে। ওহ ভাল, কোনও স্থির ভাষায় কীভাবে এটি করা যায় তা নিয়ে ভাবতে ভাবতে কেউ যখন এদিকে আসে তখন আমি এটি এখানে রেখে যাব ...


0

পাইথন 3 এর বৈকল্পিক ফাংশনগুলি কারী করার জন্য এখানে একটি সংস্করণ দেওয়া হয়েছে যা পাইথনের alচ্ছিক যুক্তিগুলির সুবিধা নিয়ে @amon এর "টার্মিনেটর" পদ্ধতির ব্যবহার করে:

def curry_vargs(g):
    actual_args = []
    def f(a, force=False):
        nonlocal actual_args
        actual_args.append(a)
        if force:
            res = g(*actual_args)
            actual_args = []
            return res
        else:
            return f
    return f

def g(*args): return sum(args)
f = curry_vargs(g)
f(1)(2)(3)(4,True) # => 10

প্রত্যাবর্তিত ফাংশনটি fবাহ্যিক স্কোপে আবদ্ধ এমন একটি অ্যারেটিতে ধারাবাহিক কলগুলিতে প্রেরিত যুক্তিগুলি সংগ্রহ করে। কেবলমাত্র forceযুক্তিটি সত্য হলেই মূল ফাংশনটি এ পর্যন্ত সংগ্রহ করা সমস্ত আর্গুমেন্টের সাথে ডাকা হয়।

এই প্রয়োগের গুহাগুলি হ'ল আপনাকে সর্বদা প্রথম যুক্তিটি পাস করতে হবে fযাতে আপনি একটি "থাঙ্ক" তৈরি করতে পারবেন না, এমন একটি ফাংশন যেখানে সমস্ত যুক্তি আবদ্ধ থাকে এবং কেবল খালি যুক্তি তালিকার সাথে ডাকা যেতে পারে (তবে আমি মনে করি এটি এর সাথে সঙ্গতিপূর্ণ) কারি এর সাধারণ প্রয়োগ)।

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

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

এটি সম্ভবত লিপ্পে সহজ হবে, কারণ লিস্পের প্রতীকগুলির একই সাথে একটি মান এবং একটি কার্যকারিতা মান থাকতে পারে; চিহ্নটি ফাংশন অবস্থানে উপস্থিত হলে (তালিকার প্রথম উপাদান হিসাবে) সহজেই ফাংশন মানটি নির্বাচন করা হয়।

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