আমি এই প্রশ্নের উত্তর দেওয়ার জন্য আরও নিয়মতান্ত্রিক পদ্ধতির প্রস্তাব দিতে চাই এবং এমন উদাহরণও দেখাতে চাই যা "নীচে" মান বা অসীম ডেটা ধরণের বা এর মতো কোনও বিশেষ কৌশল ব্যবহার করে না।
যখন টাইপ কনস্ট্রাক্টররা টাইপ বর্গের উদাহরণগুলি ব্যর্থ করে?
সাধারণত, দুটি ধরণের নির্মাতা একটি নির্দিষ্ট ধরণের শ্রেণীর উদাহরণ পেতে ব্যর্থ হতে পারে তার দুটি কারণ রয়েছে:
- প্রকার শ্রেণি থেকে প্রয়োজনীয় পদ্ধতির ধরণের স্বাক্ষরগুলি প্রয়োগ করতে পারে না।
- প্রকার স্বাক্ষরগুলি প্রয়োগ করতে পারে তবে প্রয়োজনীয় আইনগুলি সন্তুষ্ট করতে পারে না।
প্রথম ধরণের উদাহরণগুলি দ্বিতীয় ধরণেরগুলির চেয়ে সহজতর কারণ প্রথম ধরণের জন্য, আমাদের কেবলমাত্র পরীক্ষা করা দরকার যে কোনও নির্দিষ্ট ধরণের স্বাক্ষর সহ কোনও ফাংশন বাস্তবায়ন করতে পারে কিনা, তবে দ্বিতীয় ধরণের জন্য, আমাদের প্রমাণ করতে হবে যে বাস্তবায়নের কোনও প্রয়োগ নেই সম্ভবত আইনগুলি সন্তুষ্ট করতে পারে।
নির্দিষ্ট উদাহরণ
টাইপ প্যারামিটারের ক্ষেত্রে এটি একটি সংশ্লেষকারী, ফান্টেক্টর নয় a
, কারণ a
বিপরীতমুখী অবস্থানে রয়েছে। টাইপ স্বাক্ষর সহ কোনও ফাংশন বাস্তবায়ন করা অসম্ভব (a -> b) -> F z a -> F z b
।
এমন ধরণের কনস্ট্রাক্টর যা বৈধ ফান্টেক্টর নয় যদিও এর ধরণের স্বাক্ষরের fmap
প্রয়োগ করা যেতে পারে:
data Q a = Q(a -> Int, a)
fmap :: (a -> b) -> Q a -> Q b
fmap f (Q(g, x)) = Q(\_ -> g x, f x) -- this fails the functor laws!
এই উদাহরণে জানতে আগ্রহী দৃষ্টিভঙ্গি যে আমরা হয় পারেন বাস্তবায়ন fmap
সঠিক ধরনের যদিও F
সম্ভবত একটি functor হতে পারবেন না কারণ এটি ব্যবহার a
একটি contravariant অবস্থানে। সুতরাং fmap
উপরে প্রদর্শিত এই বাস্তবায়নটি বিভ্রান্তিমূলক - যদিও এর সঠিক ধরণের স্বাক্ষর রয়েছে (আমি বিশ্বাস করি এটি এই ধরণের স্বাক্ষরের একমাত্র সম্ভাব্য বাস্তবায়ন), ফান্টারের আইনগুলি সন্তুষ্ট নয়। উদাহরণস্বরূপ, fmap id
≠ id
, কারণ let (Q(f,_)) = fmap id (Q(read,"123")) in f "456"
হয় 123
, কিন্তু let (Q(f,_)) = id (Q(read,"123")) in f "456"
হয় 456
।
প্রকৃতপক্ষে, F
এটি কেবলমাত্র একটি অনুষঙ্গ, - এটি না কোনও ফান্টেক্টর এবং না কোনও কনট্রাক্টাক্টর।
একটি আইনী ফান্টেক্টর যা প্রয়োগযোগ্য নয় কারণ প্রকারের স্বাক্ষরটি pure
প্রয়োগ করা যায় না: লেখক মোনাড নিন (a, w)
এবং একরকম w
হওয়া সীমাবদ্ধতাটি সরিয়ে দিন । তখন টাইপের (a, w)
বাইরে মান নির্ধারণ করা অসম্ভব a
।
একজন functor যে আবেদন নয় কারণ ধরণ স্বাক্ষর <*>
করতে পারেন না বাস্তবায়িত হবে: data F a = Either (Int -> a) (String -> a)
।
ধরণের শ্রেণিবদ্ধ পদ্ধতি প্রয়োগ করা যেতে পারে এমন একটি ফান্টর যা আইনী প্রয়োগযোগ্য নয় :
data P a = P ((a -> Int) -> Maybe a)
টাইপ কনস্ট্রাক্টর P
একটি ফান্টেক্টর কারণ এটি a
কেবল সমবায়ীয় অবস্থানগুলিতে ব্যবহার করে।
instance Functor P where
fmap :: (a -> b) -> P a -> P b
fmap fab (P pa) = P (\q -> fmap fab $ pa (q . fab))
স্বাক্ষর প্রকারের একমাত্র সম্ভাব্য বাস্তবায়ন <*>
হ'ল একটি ফাংশন যা সর্বদা ফিরে আসে Nothing
:
(<*>) :: P (a -> b) -> P a -> P b
(P pfab) <*> (P pa) = \_ -> Nothing -- fails the laws!
তবে এই বাস্তবায়ন আবেদনকারী ফান্ট্যাক্টরদের জন্য পরিচয় আইন পূরণ করে না।
- এমন ফান্টেক্টর যা এটি
Applicative
নয় তবেMonad
এর ধরণের স্বাক্ষরটি bind
প্রয়োগ করা যায় না।
এরকম কোনও উদাহরণ আমার জানা নেই!
- একটি ফান্টেক্টর যা তবে
Applicative
তা নয়Monad
কারণ আইনগুলি স্বাক্ষর bind
করতে না পারলেও এর স্বাক্ষরের প্রকারটি কার্যকর করা যেতে পারে।
এই উদাহরণটি বেশ খানিকটা আলোচনার জন্ম দিয়েছে, সুতরাং এটি নিরাপদে বলা যায় যে এই উদাহরণটিকে সঠিক প্রমাণ করা সহজ নয়। তবে বেশ কয়েকটি ব্যক্তি এটি বিভিন্ন পদ্ধতি দ্বারা স্বাধীনভাবে যাচাই করেছেন। দেখুন `ডেটা PoE a = খালি | পেয়ার aa` একটি monad? অতিরিক্ত আলোচনার জন্য।
data B a = Maybe (a, a)
deriving Functor
instance Applicative B where
pure x = Just (x, x)
b1 <*> b2 = case (b1, b2) of
(Just (x1, y1), Just (x2, y2)) -> Just((x1, x2), (y1, y2))
_ -> Nothing
বৈধ Monad
উদাহরণ নেই তা প্রমাণ করা কিছুটা কষ্টকর । অ-monadic আচরণের কারণ হ'ল bind
যখন কোনও ফাংশন f :: a -> B b
ফিরে আসতে পারে Nothing
বা এর Just
বিভিন্ন মানের জন্য বাস্তবায়নের কোনও প্রাকৃতিক উপায় নেই a
।
এটি বিবেচনা করা সম্ভবত স্পষ্ট Maybe (a, a, a)
, যা কোনও মনাডও নয় এবং এর জন্য বাস্তবায়নের চেষ্টা করা join
। কেউ দেখতে পাবেন বাস্তবায়নের কোন স্বজ্ঞাত যুক্তিযুক্ত উপায় নেই join
।
join :: Maybe (Maybe (a, a, a), Maybe (a, a, a), Maybe (a, a, a)) -> Maybe (a, a, a)
join Nothing = Nothing
join Just (Nothing, Just (x1,x2,x3), Just (y1,y2,y3)) = ???
join Just (Just (x1,x2,x3), Nothing, Just (y1,y2,y3)) = ???
-- etc.
দ্বারা নির্দেশিত ক্ষেত্রে ???
, এটি স্পষ্ট বলে মনে হয় যে আমরা Just (z1, z2, z3)
ছয়টি ভিন্ন ধরণের মানের মধ্যে কোনও যুক্তিসঙ্গত এবং প্রতিসম পদ্ধতিতে উত্পাদন করতে পারি না a
। আমরা অবশ্যই এই ছয়টি মূল্যবোধের কিছু নির্বিচারে উপসেট বেছে নিতে পারি - উদাহরণস্বরূপ, সর্বদা প্রথম নজরে নেওয়া Maybe
- তবে এটি মোনাডের আইনগুলিকে সন্তুষ্ট করতে পারে না। ফিরে Nothing
আসা আইনগুলিও পূরণ করবে না।
- গাছের মতো ডেটা স্ট্রাকচার যা মোনাদ নয় যদিও এর জন্য সহযোগিতা রয়েছে
bind
- তবে পরিচয় আইন ব্যর্থ করে।
সাধারণ গাছের মতো মোনাদ (বা "ফান্টোর-আকৃতির শাখাযুক্ত একটি গাছ") হিসাবে সংজ্ঞায়িত করা হয়
data Tr f a = Leaf a | Branch (f (Tr f a))
এটি ফান্টারের ওপরে একটি ফ্রি মোনাদ f
। তথ্যের আকারটি এমন একটি গাছ যেখানে প্রতিটি শাখা পয়েন্ট সাবট্রির একটি "ফান্টেক্টর-ফুল" is স্ট্যান্ডার্ড বাইনারি ট্রি সাথে পাওয়া যাবে type f a = (a, a)
।
যদি আমরা f
ফান্টারের আকারে পাতা তৈরি করে এই ডেটা স্ট্রাকচারটি সংশোধন করি তবে আমি যা "সিমিমোনাদ" বলি তা অর্জন করি - এতে রয়েছে bind
প্রাকৃতিকতা এবং সমিতি সংক্রান্ত আইনগুলি সন্তুষ্ট হয় তবে এর pure
পদ্ধতিটি পরিচয় আইনের একটিতে ব্যর্থ হয়। "সেমিমনডস এন্ডোফান্টেক্টর বিভাগে সেমিগ্রুপস, সমস্যা কী?" এটি টাইপ ক্লাস Bind
।
সরলতার জন্য, আমি এর join
পরিবর্তে পদ্ধতিটি সংজ্ঞায়িত করি bind
:
data Trs f a = Leaf (f a) | Branch (f (Trs f a))
join :: Trs f (Trs f a) -> Trs f a
join (Leaf ftrs) = Branch ftrs
join (Branch ftrstrs) = Branch (fmap @f join ftrstrs)
শাখা গ্রাফটিং মানসম্মত, তবে পাতাগুলি কলমটি মানক নয় এবং একটি উত্পাদন করে Branch
। এটি সাহচর্যতা আইনের জন্য কোনও সমস্যা নয় তবে একটি পরিচয় আইন ভঙ্গ করে।
বহুবর্ষীয় ধরণের কখন মোনাদ উদাহরণ রয়েছে?
উভয়ই ফান্টেক্টর Maybe (a, a)
এবং Maybe (a, a, a)
একটি আইনী Monad
উদাহরণ দেওয়া যাবে না যদিও তারা স্পষ্টতই Applicative
।
এই ফান্টেক্টরগুলির কোনও কৌশল নেই - না Void
বা bottom
কোথাও নেই, কোনও জটিল অলসতা / কঠোরতা নেই, অসীম কাঠামো নেই, এবং কোনও ধরণের শ্রেণির বাধা নেই। Applicative
উদাহরণ হিসেবে বলা যায় সম্পূর্ণরূপে মান। ফাংশনগুলি return
এবং bind
এই ফান্ট্যাক্টারের জন্য প্রয়োগ করা যেতে পারে তবে মোনডের আইনগুলি সন্তুষ্ট করবে না। অন্য কথায়, এই ফান্টেক্টরগুলি মনড নয় কারণ একটি নির্দিষ্ট কাঠামো অনুপস্থিত (তবে ঠিক কী অনুপস্থিত তা বোঝা সহজ নয়)। উদাহরণস্বরূপ, ফান্টারের একটি ছোট পরিবর্তন এটিকে একটি মোনাদে পরিণত করতে পারে: data Maybe a = Nothing | Just a
এটি একটি মনাড। অনুরূপ আর এক ফান্টেক্টর data P12 a = Either a (a, a)
হ'ল একটি মনাদ।
বহুবর্ষীয় স্নাদের জন্য নির্মাণ
সাধারণভাবে, এখানে এমন কিছু নির্মাণ রয়েছে যা Monad
বৈধভাবে বহিরাগত ধরণের বৈধতা তৈরি করে produce এই সমস্ত নির্মাণে, M
একটি মনাদ:
type M a = Either c (w, a)
যেখানে w
কোন একরকম
type M a = m (Either c (w, a))
যেখানে m
কোনও মোনাদ এবং w
কোনও শঙ্কিত
type M a = (m1 a, m2 a)
কোথায় m1
এবং m2
কোন monads হয়
type M a = Either a (m a)
m
কোন monad যেখানে
প্রথম নির্মাণ হয় WriterT w (Either c)
, দ্বিতীয় নির্মাণ হয় WriterT w (EitherT c m)
। তৃতীয় নির্মাণ monads একটি কম্পোনেন্ট ভিত্তিক পণ্য: pure @M
এর উপাদান-অনুযায়ী পণ্য হিসাবে সংজ্ঞায়িত করা হয় pure @m1
এবং pure @m2
, এবং join @M
ক্রস পণ্য ডেটা বাদ (যেমন দ্বারা সংজ্ঞায়িত করা হয় m1 (m1 a, m2 a)
ম্যাপ করা হয় m1 (m1 a)
tuple দ্বিতীয় ভাগে বাদ দ্বারা):
join :: (m1 (m1 a, m2 a), m2 (m1 a, m2 a)) -> (m1 a, m2 a)
join (m1x, m2x) = (join @m1 (fmap fst m1x), join @m2 (fmap snd m2x))
চতুর্থ নির্মাণ হিসাবে সংজ্ঞায়িত করা হয়
data M m a = Either a (m a)
instance Monad m => Monad M m where
pure x = Left x
join :: Either (M m a) (m (M m a)) -> M m a
join (Left mma) = mma
join (Right me) = Right $ join @m $ fmap @m squash me where
squash :: M m a -> m a
squash (Left x) = pure @m x
squash (Right ma) = ma
আমি দেখেছি যে চারটি নির্মাণই আইনসম্মত স্নাতক উত্পাদন করে।
আমি অনুমান করি যে বহুবর্ষীয় মনাদের জন্য অন্য কোনও নির্মাণ নেই। উদাহরণস্বরূপ, ফ্যান্টেক্টর Maybe (Either (a, a) (a, a, a, a))
এইগুলির মধ্যে কোনও নির্মাণের মাধ্যমে প্রাপ্ত হয় না এবং তাই মোনাডিকও নয়। যাইহোক, Either (a, a) (a, a, a)
কারণ এটি তিন monads এর পণ্যে isomorphic হয় পরমাণুসদৃশ্য হয় a
, a
এবং Maybe a
। এছাড়াও, Either (a,a) (a,a,a,a)
কারণ এটি পণ্যে isomorphic হয় পরমাণুসদৃশ্য হয় a
এবং Either a (a, a, a)
।
উপরোক্ত চারটি নির্মাণ আমাদের a
উদাহরণস্বরূপ Either (Either (a, a) (a, a, a, a)) (a, a, a, a, a))
এবং এর জন্য যে কোনও সংখ্যক পণ্যগুলির যে কোনও সংখ্যার যোগফল পেতে সহায়তা করবে products এই ধরণের সমস্ত নির্মাণকারীদের (কমপক্ষে একটির) Monad
উদাহরণ থাকতে হবে।
এটি এখনও অবধি দেখতে পাওয়া যায় যে এই জাতীয় স্নাতকদের জন্য কী কী ব্যবহারের ক্ষেত্রে উপস্থিত থাকতে পারে। আরেকটি সমস্যা হ'ল Monad
নির্মাণের মাধ্যমে 1-4 থেকে প্রাপ্ত দৃষ্টান্তগুলি সাধারণভাবে অনন্য নয়। উদাহরণস্বরূপ, টাইপ কনস্ট্রাক্টরকে দুটি উপায়ে type F a = Either a (a, a)
একটি Monad
উদাহরণ দেওয়া যেতে পারে : মোনাড ব্যবহার করে 4 নির্মাণ করে এবং 3 নির্মাণের মাধ্যমে আইসোমরফিজম (a, a)
ব্যবহার করে Either a (a, a) = (a, Maybe a)
। আবার, এই বাস্তবায়নগুলির জন্য ব্যবহারের মামলাগুলি খুঁজে পাওয়া তাত্ক্ষণিকভাবে সুস্পষ্ট নয়।
একটি প্রশ্ন রয়ে গেছে - একটি স্বেচ্ছাসেবী বহুপদী ডেটা টাইপ দেওয়া হয়েছে, কীভাবে এটির Monad
উদাহরণ রয়েছে কিনা তা সনাক্ত করতে হবে । আমি জানি না কীভাবে প্রমাণ করতে পারি যে বহুবর্ষীয় স্নাতাদের জন্য অন্য কোনও নির্মাণ নেই। আমি মনে করি না এই প্রশ্নের উত্তর দেওয়ার জন্য এখনও পর্যন্ত কোনও তত্ত্ব উপস্থিত রয়েছে।
* -> *
), যার জন্য অস্তিত্ব আছে কোন উপযুক্তfmap
?