রুক্ষ ওভারভিউ
ফাংশনাল প্রোগ্রামিংয়ে, একটি ফান্টাকর মূলত নতুন এক ধরণের ভেরিয়েবলের মধ্যে ফাংশনগুলিতে সাধারণ আনারি ফাংশনগুলি (যেমন একটি যুক্তিযুক্ত) উত্তোলনের একটি নির্মাণ । প্লেইন অবজেক্টের মধ্যে সহজ ফাংশন লিখতে এবং বজায় রাখা আরও সহজ এবং সেগুলি উত্তোলনের জন্য ফান্টেক্টর ব্যবহার করে, তারপরে জটিল ধারক বস্তুর মধ্যে ম্যানুয়ালি ফাংশন লিখতে write আরও সুবিধা হ'ল কেবল একবার প্লেইন ফাংশনগুলি লিখুন এবং তারপরে এটিকে বিভিন্ন ফান্টারের মাধ্যমে পুনরায় ব্যবহার করুন।
ফান্টেক্টরের উদাহরণগুলির মধ্যে অ্যারে, "হতে পারে" এবং "হয়" ফান্টেক্টর, ফিউচার (উদাহরণস্বরূপ https://github.com/Avaq/Fl ভবিষ্যত দেখুন ) এবং আরও অনেকগুলি অন্তর্ভুক্ত রয়েছে।
চিত্রণ
প্রথম এবং শেষ নামগুলি থেকে পুরো ব্যক্তির নাম তৈরির ফাংশনটি বিবেচনা করুন। আমরা এটি fullName(firstName, lastName)
দুটি আর্গুমেন্টের ফাংশন হিসাবে সংজ্ঞায়িত করতে পারি , যা ফ্যান্টেক্টরদের পক্ষে উপযুক্ত হবে না যা কেবলমাত্র একটি যুক্তির ফাংশন নিয়ে কাজ করে। প্রতিকারের জন্য, আমরা সমস্ত যুক্তি একটি একক বস্তুতে সংগ্রহ করি name
যা এখন ফাংশনের একক যুক্তিতে পরিণত হয়:
// In JavaScript notation
fullName = name => name.firstName + ' ' + name.lastName
এখন যদি আমাদের অ্যারেতে অনেক লোক থাকে? ম্যানুয়ালি তালিকার বাইরে চলে যাওয়ার পরিবর্তে, আমরা সংক্ষিপ্ত একক লাইন কোডের সাথে অ্যারের জন্য সরবরাহিত পদ্ধতিটির fullName
মাধ্যমে আমাদের ফাংশনটি পুনরায় ব্যবহার করতে পারি map
:
fullNameList = nameList => nameList.map(fullName)
এবং এটি পছন্দ করুন
nameList = [
{firstName: 'Steve', lastName: 'Jobs'},
{firstName: 'Bill', lastName: 'Gates'}
]
fullNames = fullNameList(nameList)
// => ['Steve Jobs', 'Bill Gates']
এটি কার্যকর হবে, যখনই আমাদের প্রতিটি এন্ট্রি nameList
উভয়ই firstName
এবং lastName
সম্পত্তি সরবরাহ করে। তবে কিছু জিনিস যদি না (বা এমনকি বস্তুগুলি নাও হয়)? ত্রুটিগুলি এড়ানোর জন্য এবং কোডটি আরও নিরাপদ করার জন্য আমরা আমাদের বস্তুগুলিকে Maybe
প্রকারের মধ্যে আবদ্ধ করতে পারি (উদাহরণস্বরূপ https://sanctury.js.org/#maybe-type ):
// function to test name for validity
isValidName = name =>
(typeof name === 'object')
&& (typeof name.firstName === 'string')
&& (typeof name.lastName === 'string')
// wrap into the Maybe type
maybeName = name =>
isValidName(name) ? Just(name) : Nothing()
যেখানে Just(name)
কেবলমাত্র বৈধ নাম বহনকারী একটি ধারক এবং Nothing()
অন্য সমস্ত কিছুর জন্য ব্যবহৃত বিশেষ মান। এখন আমাদের আর্গুমেন্টগুলির বৈধতা পরীক্ষা করতে বাধা (বা ভুলে যাওয়া) পরিবর্তে, আমরা পদ্ধতিটির fullName
উপর ভিত্তি করে আমাদের মূল ফাংশনটি অন্য একটি একক লাইনের সাথে পুনরায় ব্যবহার করতে পারি (উত্তোলন করতে পারি) map
, এবার টাইপের জন্য সরবরাহ করা যেতে পারে:
// Maybe Object -> Maybe String
maybeFullName = maybeName => maybeName.map(fullName)
এবং এটি পছন্দ করুন
justSteve = maybeName(
{firstName: 'Steve', lastName: 'Jobs'}
) // => Just({firstName: 'Steve', lastName: 'Jobs'})
notSteve = maybeName(
{lastName: 'SomeJobs'}
) // => Nothing()
steveFN = maybeFullName(justSteve)
// => Just('Steve Jobs')
notSteveFN = maybeFullName(notSteve)
// => Nothing()
বিভাগ তত্ত্ব
একজন Functor মধ্যে শ্রেণী তত্ত্ব দুটি বিভাগ তাদের morphisms রচনা সম্মান মধ্যে একটি মানচিত্র। একটি কম্পিউটার ভাষা , সুদের প্রধান শ্রেণী যার হয় বস্তু হয় ধরনের (মূল্যবোধের নির্দিষ্ট সেট), এবং যার morphisms হয় ফাংশন f:a->b
এক ধরনের থেকে a
অন্য ধরনের b
।
উদাহরণস্বরূপ, নিতে a
হতে String
ধরন, b
নম্বর টাইপ করুন, এবং f
ফাংশন তার দৈর্ঘ্য মধ্যে একটি স্ট্রিং ম্যাপিং হল:
// f :: String -> Number
f = str => str.length
এখানে a = String
সমস্ত স্ট্রিংয়ের b = Number
সেট এবং সমস্ত সংখ্যার সেট উপস্থাপন করা হয়। যে অর্থে, উভয় a
এবং b
বস্তু প্রতিনিধিত্ব সেট শ্রেণী (যা ঘনিষ্ঠভাবে পার্থক্য অদরকারী এখানে হচ্ছে ধরনের শ্রেণীবিভাগের উপর নিরভরশীল নেই)। সেট বিভাগে, দুটি সেটগুলির মধ্যে আকারগুলি প্রথম সেট থেকে দ্বিতীয়টিতে অবিকল সমস্ত ফাংশন। সুতরাং f
এখানে আমাদের দৈর্ঘ্যের ফাংশনটি স্ট্রিংয়ের সেট থেকে সংখ্যার সেটে একটি রূপচর্চা।
যেহেতু আমরা কেবল সেট বিভাগটি বিবেচনা করি, এর থেকে প্রাসঙ্গিক ফ্যান্ট্যাক্টররা নিজেরাই অবজেক্টগুলিকে বস্তুগুলিকে এবং মরফিজমে মরফিজমগুলিতে প্রেরণ করে এমন মানচিত্র যা নির্দিষ্ট বীজগণিত আইনকে সন্তুষ্ট করে।
উদাহরণ: Array
Array
অনেকগুলি জিনিস বোঝাতে পারে তবে কেবল একটি জিনিস হ'ল ফান্ট্যাক্ট - টাইপ কনস্ট্রাক্ট, a
টাইপের [a]
সমস্ত অ্যারে টাইপের মধ্যে ম্যাপিং করে a
। উদাহরণস্বরূপ, Array
ফান্টর প্রকারটি String
টাইপ করে [String]
(স্বেচ্ছাসেবী দৈর্ঘ্যের সমস্ত অ্যারের সেট), এবং সেট প্রকারটিকে Number
সংশ্লিষ্ট ধরণের [Number]
(সংখ্যার সমস্ত অ্যারেগুলির সেট ) মধ্যে ম্যাপ করে ।
ফান্টেক্টর মানচিত্রটিকে বিভ্রান্ত না করা গুরুত্বপূর্ণ
Array :: a => [a]
একটি আকারে সঙ্গে a -> [a]
। Functor কেবল মানচিত্র (সহযোগীদের) টাইপ a
টাইপ মধ্যে [a]
অন্য এক জিনিস না। প্রতিটি প্রকারটি আসলে উপাদানগুলির একটি সেট, এখানে এখানে কোনও প্রাসঙ্গিকতা নেই। বিপরীতে, একটি মরফিজম সেই সেটগুলির মধ্যে একটি আসল ফাংশন। উদাহরণস্বরূপ, একটি প্রাকৃতিক আকার আছে (ফাংশন)
pure :: a -> [a]
pure = x => [x]
যা একক এন্ট্রি হিসাবে সেই মান সহ 1-উপাদান অ্যারেতে একটি মান প্রেরণ করে। সেই ফাংশনটি ফান্টাক্টরের কোনও অংশ নয়Array
! এই ফান্টারের দৃষ্টিকোণ থেকে, অন্য যেগুলির pure
মতো কেবল একটি ফাংশন, বিশেষ কিছু নয়।
অন্যদিকে, Array
ফান্টাকারের দ্বিতীয় অংশ রয়েছে - মরফিজমের অংশ। কোনটি morphism মানচিত্র f :: a -> b
একটি morphism মধ্যে [f] :: [a] -> [b]
:
// a -> [a]
Array.map(f) = arr => arr.map(f)
এখানে arr
টাইপ মান নির্বিচারে দৈর্ঘ্যের কোনো অ্যারে a
, এবং arr.map(f)
টাইপ মান সঙ্গে একই দৈর্ঘ্যের অ্যারে b
, যার এন্ট্রি প্রয়োগের ফলাফল নেই f
এর টি এন্ট্রির মধ্যে arr
। এটিকে ফান্টাকর করার জন্য, পরিচয়ের সাথে পরিচয়ের মানচিত্র তৈরির গাণিতিক আইন এবং রচনাগুলিতে রচনাগুলি আবশ্যক, যা এই Array
উদাহরণে পরীক্ষা করা সহজ ।