এফ # তে বিভিন্ন ধরণের জন্য কেন এতগুলি `মানচিত্র` ফাংশন রয়েছে?


9

আমি F # শিখছি। আমি হাস্কেল দিয়ে এফপি শুরু করেছি এবং এর জন্য আমি কৌতূহল পেয়েছি।

যেহেতু এফ # হ'ল নেট ভাষা, তাই Mappableহ্যাশেল Functorটাইপ শ্রেণীর মতো ইন্টারফেসের মতো ঘোষণা করা আমার পক্ষে আরও যুক্তিযুক্ত বলে মনে হয় ।

এখানে চিত্র বর্ণনা লিখুন

তবে উপরের ছবির মতো, এফ # ফাংশনগুলি পৃথক করে এর নিজস্ব হিসাবে প্রয়োগ করা হয়। এই জাতীয় নকশার নকশা উদ্দেশ্য কী? আমার Mappable.mapজন্য, প্রতিটি ডেটা টাইপের জন্য এটি প্রবর্তন করা এবং প্রয়োগ করা আরও সুবিধাজনক হবে।


এই প্রশ্নটি এসও সম্পর্কিত নয়। এটি কোনও প্রোগ্রামিং সমস্যা নয়। আমি আপনাকে এফ # স্ল্যাক বা অন্য কোনও আলোচনা ফোরামে জিজ্ঞাসা করব।
বেন্ট ট্রানবার্গ

5
@ বেন্টট্রানবার্গ উদারভাবে পড়েন, The community is here to help you with specific coding, algorithm, or language problems.ভাষা নকশা প্রশ্নগুলিও অন্তর্ভুক্ত রাখবেন যতক্ষণ না অন্যান্য মানদণ্ডগুলি পরিপূর্ণ হয়।
কাইফার

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

উত্তর:


19

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

প্রথমত, অবশ্যই, আপনি ইতিমধ্যে সঠিকভাবে আবিষ্কার করেছেন যে এফ # এর টাইপ ক্লাস নেই, এবং এ কারণেই। তবে আপনি একটি ইন্টারফেস প্রস্তাব Mappable। ঠিক আছে, আসুন এটি খতিয়ে দেখা যাক।

ধরা যাক আমরা এই জাতীয় ইন্টারফেস ঘোষণা করতে পারি। আপনি কি ভাবতে পারেন যে এর স্বাক্ষরটি কেমন হবে?

type Mappable =
    abstract member map : ('a -> 'b) -> 'f<'a> -> 'f<'b>

কোথায় fযে ধরনের ইন্টারফেস বাস্তবায়ন করছে। অপেক্ষা কর! এফ # এরও নেই! এখানে fএকটি উচ্চ ধরণের ধরণের পরিবর্তনশীল এবং এফ # তে মোটামুটি উচ্চ-দয়ালুতা নেই। কোনও ক্রিয়া f : 'm<'a> -> 'm<'b>বা এর মতো কিছু ঘোষণা করার কোনও উপায় নেই ।

তবে ঠিক আছে, ধরা যাক আমরা সেই প্রতিবন্ধকতাটিও পেরেছি। আর এখন আমরা একটি ইন্টারফেস থাকতে Mappableযে দ্বারা প্রয়োগ করা যাবে List, Array, Seq, এবং রান্নাঘরের সিংক। কিন্তু অপেক্ষা করো! এখন আমাদের কাছে একটি ফাংশনের পরিবর্তে একটি পদ্ধতি রয়েছে এবং পদ্ধতিগুলি ভাল রচনা করে না! আসুন নেস্টেড তালিকার প্রতিটি উপাদানগুলিতে 42 যোগ করার দিকে নজর দিন:

// Good ol' functions:
add42 nestedList = nestedList |> List.map (List.map ((+) 42))

// Using an interface:
add42 nestedList = nestedList.map (fun l -> l.map ((+) 42))

দেখুন: এখন আমাদের ল্যাম্বডা এক্সপ্রেশন ব্যবহার করতে হবে! এই .mapবাস্তবায়নটিকে কোনও মান হিসাবে অন্য ফাংশনে পাস করার কোনও উপায় নেই । কার্যকরভাবে "মান হিসাবে ফাংশন" এর সমাপ্তি (এবং হ্যাঁ, আমি জানি, ল্যাম্বডা ব্যবহার করা এই উদাহরণে খুব খারাপ দেখাচ্ছে না, তবে আমার উপর বিশ্বাস করুন, এটি খুব কুৎসিত হয়)

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

add42 (nestedList : #Mappable) = nestedList.map (fun l -> l.map ((+) 42))

ওহ, তবে এটি এখনও যথেষ্ট নয়! যদিও আমি nestedListনিজের জন্য একটি স্বাক্ষর সরবরাহ করেছি , আমি ল্যাম্বদার প্যারামিটারের জন্য একটি স্বাক্ষর সরবরাহ করিনি l। এ জাতীয় স্বাক্ষর কী হওয়া উচিত? তুমি কি বলবে এটা হওয়া উচিত fun (l: #Mappable) -> ...? ওহ, এবং এখন অবশেষে আমরা র‌্যাঙ্ক-এন প্রকারগুলি পেয়েছি, আপনি দেখতে পাচ্ছেন, #Mappable"কোনও ধরণের 'aধরণের 'a :> Mappable" - এর অর্থ একটি ল্যাম্বডা এক্সপ্রেশন যা নিজেই জেনেরিক for

অথবা, বিকল্পভাবে, আমরা আবার উচ্চতর দয়ালুতে ফিরে যেতে পারি এবং nestedListআরও প্রকারের স্পষ্টভাবে ঘোষণা করতে পারি :

add42 (nestedList : 'f<'a<'b>> where 'f :> Mappable, 'a :> Mappable) = ...

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

add42 nestedList = nestedList.map (.map ((+) 42))

কি ধরণের .mapহবে? এটি হাসেলেলের মতোই সীমাবদ্ধ ধরনের হতে হবে !

.map : Mappable 'f => ('a -> 'b) -> 'f<'a> -> 'f<'b>

ওহ, ঠিক আছে. .NET এমনকি এই ধরণের প্রকারের অস্তিত্ব দেয় না এই বিষয়টি বাদ দিয়ে কার্যকরভাবে আমরা সবেমাত্র টাইপ ক্লাস পেয়েছি!

তবে এমন একটি কারণ রয়েছে যে F # এর প্রথম শ্রেণিতে টাইপ ক্লাস নেই। সে কারণে অনেক দিক উপরে বর্ণিত হয়েছে, তবে এটির আরও একটি সংক্ষিপ্ত উপায় হ'ল সরলতা

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

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

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

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

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