একটি ইন্টারফেসের ক্রিয়ামূলক-প্রোগ্রামিং বিকল্প কি?


15

আমি যদি "ফাংশনাল" স্টাইলে প্রোগ্রাম করতে চাই, তবে আমি কোন ইন্টারফেসটি প্রতিস্থাপন করব?

interface IFace
{
   string Name { get; set; }
   int Id { get; }
}
class Foo : IFace { ... }

হতে পারে একটি Tuple<>?

Tuple<Func<string> /*get_Name*/, Action<String> /*set_Name*/, Func<int> /*get_Id*/> Foo;

আমি প্রথম স্থানে ইন্টারফেসটি ব্যবহার করার একমাত্র কারণ হ'ল আমি সর্বদা নির্দিষ্ট বৈশিষ্ট্য / পদ্ধতি উপলভ্য চাই।


সম্পাদনা করুন: আমি কী ভাবছি / চেষ্টা করছি সে সম্পর্কে আরও কিছু বিশদ।

বলুন, আমি একটি পদ্ধতি পেয়েছি যা তিনটি ফাংশন গ্রহণ করে:

static class Blarf
{
   public static void DoSomething(Func<string> getName, Action<string> setName, Func<int> getId);
}

একটি উদাহরণ সহ Barআমি এই পদ্ধতিটি ব্যবহার করতে পারি:

class Bar
{
   public string GetName();
   public void SetName(string value);

   public int GetId();
}
...
var bar = new Bar();
Blarf.DoSomething(bar.GetName, bar.SetName, bar.GetId);

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

Blarf.DoSomething(bar1.GetName, bar2.SetName, bar3.GetId); // NO!

সি # তে, interfaceএটির সাথে মোকাবিলা করার একটি উপায় হল; তবে এটি খুব অবজেক্ট-ভিত্তিক পদ্ধতির মতো বলে মনে হচ্ছে। আমি আরও ভাবছি যে আরও কার্যকরী সমাধান আছে কিনা: 1) ফাংশনগুলির গ্রুপ একসাথে পাস করুন এবং 2) ফাংশনগুলি একে অপরের সাথে সঠিকভাবে সম্পর্কিত কিনা তা নিশ্চিত করুন।


আপনি না। ডেটাটাইপগুলির জন্য ইন্টারফেসগুলি পুরোপুরি ঠিক আছে (যদিও আপনি অপরিবর্তনীয় বস্তুর পক্ষে থাকবেন)।
টেলাস্টিন

1
এসআইসপির দ্বিতীয় অধ্যায়টি এটি সম্পর্কে বেশ কিছু।
ব্যবহারকারী16764

7
আপনার প্রশ্নটি পড়ার পরে, আমি আগ্রহী যে আপনি কোন নির্দিষ্ট কার্যকারিতাটি সম্পাদনের চেষ্টা করছেন? আপনি যা জিজ্ঞাসা করছেন বলে মনে হচ্ছে তা হল কীভাবে কার্যক্ষম শৈলীতে একটি উদাহরণের বিরুদ্ধে ওও স্টাইলের পার্শ্ব-কার্যকরী প্রোগ্রামিন করা যায়, যা কোনও অর্থ হয় না ..
জিমি হোফা

উত্তরটি ভাষা নির্ভর হবে। ক্লোজুরে আপনি ক্লোজিউর.আর / প্রোটোকলগুলি ব্যবহার করতে পারেন , যেখানে একমাত্র নরম অঞ্চলটি হ'ল ধরণের পরামিতিগুলি যে ফাংশনগুলি পরিচালনা করতে হবে - সেগুলি একটি বস্তু - এটি আপনারা জানেন।
চাকরী

1
এটিকে সহজ করুন: একটি স্ট্রাক্ট যার মধ্যে রয়েছে সেই পদ্ধতি পয়েন্টার, এবং কোনও ফাংশন এটি কোনও বস্তুর উদাহরণ থেকে সূচনা করার জন্য। হাস্কেল কেন? ;)
mlvljr

উত্তর:


6

অপরিহার্য প্রোগ্রামিংয়ের তুলনায় ফাংশনাল প্রোগ্রামিংকে একটি পাতলা ব্যহ্যা হিসাবে বিবেচনা করবেন না; কেবল একটি সিনট্যাকটিক পার্থক্য ছাড়াও আরও অনেক কিছু রয়েছে।

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


3
"আপনাকে অবশ্যই রাশিয়ান ভাষায় ভাবতে হবে ।"
Ðаn

যথেষ্ট ফর্সা; আমার আসল সমস্যাটি বিশেষ আকর্ষণীয় নয়। আমি ইতিমধ্যে সি # ( github.com/JDanielSmith/Projects/tree/master/PictureOfTheDe এ ঠিক মত কাজ করার জিনিসগুলি পেয়েছি ) তবে আপনি যদি আরও সত্যিকারের কোডটি দেখতে চান তবে) তবে এটি আরও কার্যকরী শৈলীতে কাজ করা মজা হবে while এখনও সি # ব্যবহার করছে।
Ðаn

1
@ ?N আসলেই কি কোনও ফায়ারফক্স (ফিল্ম) উদ্ধৃতি (কারণ এটি যদি দুর্দান্ত হয়)? বা এটি অন্য কোথাও ব্যবহার করা হয়?
icc97

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

11

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


5
টাইপক্লাসের জন্য +1 - হাস্কেল টাইপক্লাস এবং জাভা ইন্টারফেসের মধ্যে প্রধান পার্থক্য হ'ল উভয় পৃথকভাবে ঘোষণার পরে টাইপক্লাস টাইপের সাথে যুক্ত । আপনি কোনও নতুন "ইন্টারফেস" এর মাধ্যমে কোনও পুরানো প্রকারটি সহজেই ব্যবহার করতে পারেন যেমন কোনও নতুন ধরণের অ্যাক্সেসের জন্য আপনি কোনও পুরানো "ইন্টারফেস" ব্যবহার করতে পারেন। ডেটা লুকানোর জন্য, আপনি মডিউলে টাইপের প্রয়োগটি গোপন করেন। অনুযায়ী কমপক্ষে আইফেল খ্যাতির বারট্রান্ড মেয়ার , একটি গলি বর্গ হয় মডিউল এক ধরনের।
স্টিভ 314

5

একাধিক ইনপুট মোকাবেলায় কোনও ফাংশনকে অনুমতি দেওয়ার কয়েকটি উপায় রয়েছে।

প্রথম এবং সর্বাধিক সাধারণ: প্যারামেট্রিক পলিমারফিজম।

এটি স্বেচ্ছাসেবী প্রকারের উপর একটি ফাংশন কাজ করতে দেয়:

--Haskell Example
id :: a -> a --Here 'a' is just some arbitrary type
id myRandomThing = myRandomThing

head :: [a] -> a
head (listItem:list) = listItem

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

class Addable a where
   (<+>) :: a -> a -> a
instance Addable Int where
   a <+> b = a + b
instance Addable [a] where
   a <+> b = a ++ b

--Now we can get that do something similar to OO (kinda...)
addStuff :: (Addable a) => [a] -> a
-- Notice how we limit 'a' here to be something Addable
addStuff (x:[]) = x
addStuff (x:xs) = x <+> addStuff xs
-- In better Haskell form
addStuff' = foldl1 <+>

এই দুটি পদ্ধতির মধ্যে, আপনি নিজের ধরণের বিভিন্ন ধরণের জটিল এবং আকর্ষণীয় আচরণ প্রকাশ করতে পারেন।


1
উত্তরের ভাষা যখন প্রশ্নের ভাষার সাথে মেলে না তখন আপনি সিনট্যাক্স হাইলাইটিং ইঙ্গিতগুলি যুক্ত করতে পারেন । উদাহরণস্বরূপ আমার প্রস্তাবিত সম্পাদনা দেখুন।
hugomg

1

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

var make_OO_style_counter = function(){
   return {
      counter: 0
      increment: function(){
          this.counter += 1
          return this.counter;
      }
   }
};

var make_FP_style_counter = function(){
    var counter = 0;
    return fucntion(){
        counter += 1
        return counter;
    }
};

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

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

var my_blarfable = {
 get_name: function(){ ... },
 set_name: function(){ ... },
 get_id:   function(){ ... }
}

do_something(my_blarfable)

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

-- Explicit dictionary version
-- no setters because haskell doesn't like mutable state.
data BlargDict = BlargDict {
    blarg_name :: String,
    blarg_id   :: Integer
}

do_something :: BlargDict -> IO()
do_something blarg_dict = do
   print (blarg_name blarg_dict)
   print (blarg_id   blarg_dict)

-- Typeclass version   
class Blargable a where
   blag_name :: a -> String
   blag_id   :: a -> String

do_something :: Blargable a => a -> IO
do_something blarg = do
   print (blarg_name blarg)
   print (blarg_id   blarg)

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

[1] "অস্তিত্বের ধরণগুলি" করার জন্য আরও উন্নত উপায় রয়েছে তবে এটি সাধারণত সমস্যার জন্য উপযুক্ত নয়।


0

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

;; returns a function of the type #'(lambda (x y z &optional a b c)

(defun get-higher-level-method-impl (some-type-of-qualifier) 
    (cond ((eq 'foo) #'the-foo-version)
          ((eq 'bar) #'the-bar-version)))
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.