আবেদনকারীরা রচনা করুন, মনদেহগুলি না


110

আবেদনকারীরা রচনা করুন, মনদেহগুলি না।

উপরের বিবৃতিটির অর্থ কী? এবং কখন একজনের চেয়ে অপরটি পছন্দযোগ্য?


5
আপনি এই বিবৃতিটি কোথা থেকে পেয়েছেন? এটি কিছু প্রসঙ্গে দেখার জন্য সহায়ক হতে পারে।
ফুজ

@ ফুজজেক্সএল: আমি টুইটারে সম্প্রতি ডিবাশিংগ থেকে বহু লোকের কাছ থেকে এটি বারবার শুনেছি।
মিসিংফ্যাক্টর

3
@stephen tetley: নোট যে অনেক ধরনের Applicativeগুলি আসলে একটি সুস্থ লোকের পরিবার এর Monadগুলি, যথা গঠন সম্ভব প্রতিটি "আকৃতি" জন্য। ZipListএকটি নয় Monad, তবে ZipListএকটি নির্দিষ্ট দৈর্ঘ্যের। Readerএকটি সুবিধাজনক বিশেষ (বা এটি সাধারণ?) ক্ষেত্রে যেখানে "কাঠামোর" আকারটি পরিবেশের ধরণের কার্ডিনালিটি হিসাবে স্থির করা হয়।
সিএ ম্যাকক্যান

3
@ ক্যাম্যাকক্যান এই সমস্ত জিপি আবেদনকারীরা (তারা কাটা হোক বা প্যাড হোক) মোডগুলিতে সীমাবদ্ধ রাখুন যদি আপনি কোনও আকারকে আইসোমরফিজম অবধি এমনভাবে স্থির করেন তবে Reader। একবার আপনি কোনও ধারকটির আকারটি ঠিক করার পরে, এটি মেমো ট্রাইয়ের মতো অবস্থান থেকে কোনও কার্যকরীভাবে কার্যকরভাবে এনকোড করে। পিটার হ্যানকক এ জাতীয় ফান্টেক্টরকে "ন্যাপারিয়ান" বলে ডাকে কারণ তারা লগারিদমের আইন মেনে চলে।
শূকরকর্ম

4
@ স্টেফেন টেটলি: অন্যান্য উদাহরণগুলির মধ্যে ধ্রুবক-মনোয়েড অ্যাপ্লিয়েটিভ (যা মনাদগুলির রচনা তবে মনাদ নয়) এবং ইউনিট-বিলম্বিত আবেদনকারী (যা ভালভাবে যোগদানের স্বীকৃতি দেয়নি) অন্তর্ভুক্ত করে।
পিগ ওয়ার্কার

উত্তর:


115

যদি আমরা প্রকারগুলি তুলনা করি

(<*>) :: Applicative a => a (s -> t) -> a s -> a t
(>>=) :: Monad m =>       m s -> (s -> m t) -> m t

দুটি ধারণাটি কী আলাদা করে তার জন্য আমরা একটি সূত্র পাই। যে (s -> m t)এ ধরণের (>>=)শো যে একটি মান sএকটি গণনার আচরণকে নির্ধারণ করতে পারেন m t। মনডস মান এবং গণনার স্তরগুলির মধ্যে হস্তক্ষেপের অনুমতি দেয়। (<*>)অপারেটর ধরনের কোনো হস্তক্ষেপ অনুমতি দেয়: ফাংশন এবং যুক্তি কম্পিউটেশন মান উপর নির্ভর করে না। এই সত্যিই কামড়। তুলনা করা

miffy :: Monad m => m Bool -> m x -> m x -> m x
miffy mb mt mf = do
  b <- mb
  if b then mt else mf

যা দুটি গুণনার মধ্যে সিদ্ধান্ত নিতে কিছু প্রভাবের ফলাফলকে ব্যবহার করে (উদাহরণস্বরূপ ক্ষেপণাস্ত্র উৎক্ষেপণ এবং একটি অস্ত্রশস্ত্র স্বাক্ষর)

iffy :: Applicative a => a Bool -> a x -> a x -> a x
iffy ab at af = pure cond <*> ab <*> at <*> af where
  cond b t f = if b then t else f

যা দুটি গণনার মানগুলিরab মধ্যে চয়ন করতে এবং উভয়ই সম্পাদন করে, সম্ভবত করুণ প্রভাবের জন্য ব্যবহার করে usesataf

মোনাডিক সংস্করণ মূলত (>>=)কোনও মান থেকে গণনা চয়ন করার অতিরিক্ত শক্তির উপর নির্ভর করে এবং এটি গুরুত্বপূর্ণ হতে পারে। যাইহোক, সেই শক্তিটিকে সমর্থন করা মনডকে রচনা করা শক্ত করে। আমরা যদি 'ডাবল-বাইন্ড' তৈরির চেষ্টা করি

(>>>>==) :: (Monad m, Monad n) => m (n s) -> (s -> m (n t)) -> m (n t)
mns >>>>== f = mns >>-{-m-} \ ns -> let nmnt = ns >>= (return . f) in ???

আমরা এটি এখন পর্যন্ত পেয়েছি, কিন্তু এখন আমাদের স্তরগুলি সমস্ত স্তম্ভিত হয়েছে। আমাদের একটি আছে n (m (n t)), তাই আমাদের বাইরের দিক থেকে মুক্তি দেওয়া দরকার n। যেমন আলেকজান্দ্রি সি বলেছেন, আমাদের যদি উপযুক্ত থাকে তবে আমরা তা করতে পারি

swap :: n (m t) -> m (n t)

nভিতরের দিকে এবং joinএটি অন্যটিতে ক্রমানুসারে n

দুর্বল 'ডাবল-প্রয়োগ' সংজ্ঞা দেওয়া অনেক সহজ

(<<**>>) :: (Applicative a, Applicative b) => a (b (s -> t)) -> a (b s) -> a (b t)
abf <<**>> abs = pure (<*>) <*> abf <*> abs

কারণ স্তরগুলির মধ্যে কোনও হস্তক্ষেপ নেই।

স্বতঃস্ফূর্তভাবে, যখন আপনার সত্যিকারের অতিরিক্ত পাওয়ার প্রয়োজন হয় Monadএবং আপনি যখন কঠোর গণনার কাঠামো Applicativeসমর্থন করেন সেগুলি থেকে দূরে সরে যেতে পারেন তা স্বীকার করা ভাল ।

দ্রষ্টব্য, যাইহোক, যদিও মণাদ রচনা করা কঠিন, এটি আপনার প্রয়োজনের চেয়ে বেশি হতে পারে। প্রকারটি -আফেক্টগুলির m (n v)সাথে কম্পিউটিং নির্দেশ করে m, তারপরে n-আফেক্টগুলির সাথে একটি- vএ্যালুয়েলে গণনা করে, যেখানে- mপ্রভাবগুলি -আফেক্টগুলি শুরু হওয়ার আগে শেষ হয় n(অতএব প্রয়োজনীয়তা swap)। যদি আপনি কেবল- mপ্রভাবগুলির সাথে ইন্টারলিভ করতে চান n, তবে রচনাটি সম্ভবত জিজ্ঞাসা করার জন্য খুব বেশি!


3
ইফফির উদাহরণ হিসাবে আপনি উল্লেখ করেছেন যে এটি "দু'টি গণনার মান এবং এএফএফের মধ্যে দুটি নির্বাচন করে সম্ভবত দু: খজনক প্রভাব ফেলতে ব্যবহার করে আবের মান ব্যবহার করে।" হাস্কেলের অলস প্রকৃতি কি আপনাকে এ থেকে রক্ষা করে না? আমার কাছে যদি তালিকা = (\ বিটিএফ -> বি থাকে তবে অন্য চ): [] এবং তারপরে বিবৃতিটি কার্যকর করুন: তালিকা <*> খাঁটি সত্য <*> খাঁটি "হ্যালো" <*> খাঁটি (ত্রুটি "খারাপ")। ... আমি "হ্যালো" পেয়েছি এবং ত্রুটিটি কখনই ঘটে না। এই কোডটি একটি মোনাডের মতো প্রায় নিরাপদ বা নিয়ন্ত্রিত নয় তবে পোস্টটি মনে হচ্ছে এটি প্রয়োগকারীদের কঠোর মূল্যায়নের কারণ হিসাবে প্রস্তাবিত। সামগ্রিকভাবে দুর্দান্ত পোস্ট যদিও! ধন্যবাদ!
shj

7
আপনি এখনও উভয়ের প্রভাব পান তবে বিশুদ্ধ (ত্রুটি "খারাপ") এর কোনওটিই নেই। অন্যদিকে, আপনি যদি ইফফি (খাঁটি সত্য) (খাঁটি "হ্যালো") (ত্রুটি "খারাপ") চেষ্টা করেন তবে আপনি এমন একটি ত্রুটি পাবেন যা পরিহার করবে তদতিরিক্ত, আপনি যদি ifif (খাঁটি সত্য) (খাঁটি 0) [1,2] এর মতো কিছু চেষ্টা করেন তবে আপনি [0] এর পরিবর্তে [0,0] পাবেন। আবেদনকারীদের তাদের সম্পর্কে একধরনের কঠোরতা রয়েছে, এতে তারা গণনার নির্দিষ্ট সিকোয়েন্স তৈরি করে, তবে এই গণনাগুলির ফলে প্রাপ্ত মানগুলি এখনও আলস্যভাবে সংযুক্ত করা হয়, যেমন আপনি পর্যবেক্ষণ করেছেন।
পিগ ওয়ার্কার

এটা কি সত্য, যে কোনো monads জন্য mএবং nআপনি সবসময় এমন একটি একসংখ্যা ট্রান্সফরমার লিখতে পারেন mt, এবং কাজ n (m t)ব্যবহার mt n t? সুতরাং আপনি সর্বদা মনড রচনা করতে পারেন, এটি ট্রান্সফর্মার ব্যবহার করে আরও জটিল?
রন

4
এই ধরনের ট্রান্সফর্মার প্রায়শই বিদ্যমান থাকে তবে আমি যতদূর জানি, সেগুলি উত্পন্ন করার কোনও প্রথাগত উপায় নেই। বিভিন্ন মনড থেকে আন্তঃবিবাহিত প্রভাবগুলি কীভাবে সমাধান করা যায় সে সম্পর্কে প্রায়শই একটি আসল পছন্দ রয়েছে, এর ব্যতিক্রম এবং উদাহরণ ব্যতিক্রম। ব্যতিক্রম রাষ্ট্রের পরিবর্তন ফিরে আসা উচিত? উভয় পছন্দ তাদের জায়গা আছে। এটি বলার পরে, একটি "ফ্রি মোনাড" জিনিস রয়েছে যা "স্বেচ্ছাসেবী আন্তঃবিভাজন" প্রকাশ করে। data Free f x = Ret x | Do (f (Free f x)), তারপর data (:+:) f g x = Inl (f x) | Tnr (g x), এবং বিবেচনা করুন Free (m :+: n)। এটি কীভাবে আন্তঃবিভাজন চালানো যায় তা চয়ন করতে বিলম্ব করে।
পিগ ওয়ার্কার

@ পিগ ওয়ার্কার অলস / কঠোর বিতর্ক সম্পর্কিত। আমি মনে করি যে আবেদনকারীদের সাথে আপনি গণনার মধ্যে থেকে প্রভাবটি নিয়ন্ত্রণ করতে পারবেন না , তবে এফেক্ট-স্তরটি পরবর্তী মানগুলির মূল্যায়ন না করার সিদ্ধান্ত নিতে পারে। (প্রয়োগকারী) পার্সারদের জন্য এর অর্থ হ'ল পার্সার তাড়াতাড়ি ব্যর্থ হলে পরবর্তী পার্সারগুলি ইনপুটটিতে মূল্যায়ন / প্রয়োগ করা হয় না। এর Maybeঅর্থ এটি যে প্রথম দিকে পরবর্তী / পরবর্তীগুলির Nothingমূল্যায়ন দমন করবে । এটা কি সঠিক? aJust a
ziggystar

75

আবেদনকারীরা রচনা করুন, মনদেহগুলি না।

Monads না রচনাতে কিন্তু এর ফলে একসংখ্যা নাও হতে পারে। বিপরীতে, দুটি আবেদনকারীর সমন্বয়টি অবশ্যই একজন আবেদনকারী। আমি সন্দেহ করি যে মূল বক্তব্যটির উদ্দেশ্যটি ছিল "প্রয়োগযোগ্যতা রচনা করে, যদিও একাকীত্ব হয় না।" পুনঃপ্রকাশিত, " Applicativeরচনা অধীনে বন্ধ আছে, এবং Monadতা নয়।"


24
অতিরিক্তভাবে, যে কোনও দুটি আবেদনকারী সম্পূর্ণ যান্ত্রিক উপায়ে রচনা করেন, যেখানে দুটি মনডের সমন্বয়ে গঠিত মনড সেই রচনার জন্য নির্দিষ্ট।
অ্যাপোক্যালিস্প

12
অন্যদিকে মনাদগুলি অন্যান্য উপায়ে রচনা করেন, দুটি স্নাতকের পণ্যটি একটি মোনাদ, এটি কেবল সেই কপোড্রাক্টই যেগুলি একরকম বিতরণের আইন প্রয়োজন need
এডওয়ার্ড কেএমইটিটি

@ অ্যাপোকালিস্প সহ মন্তব্যটি অন্তর্ভুক্ত রয়েছে, এটি সেরা এবং সবচেয়ে সংক্ষিপ্ত উত্তর।
পল ড্রাগার

39

আপনার যদি আবেদনকারী রয়েছে A1এবং A2, তবে টাইপটি data A3 a = A3 (A1 (A2 a))প্রযোজ্যও (আপনি জেনেরিক উপায়ে এ জাতীয় উদাহরণ লিখতে পারেন)।

অন্যদিকে, যদি আপনার কাছে মোনাদ থাকে M1এবং M2তবে টাইপটি data M3 a = M3 (M1 (M2 a))অগত্যা একটি মোনাড নয় ( রচনাটির জন্য >>=বা এর joinজন্য কোনও বুদ্ধিমান জেনেরিক প্রয়োগ নেই )।

একটা উদাহরণ ধরনের হতে পারে [Int -> a](এখানে আমরা একটি টাইপ কন্সট্রাকটর রচনা []সঙ্গে (->) Int, এই দুই ধরনের monads হয়)। আপনি সহজেই লিখতে পারেন

app :: [Int -> (a -> b)] -> [Int -> a] -> [Int -> b]
app f x = (<*>) <$> f <*> x

এবং এটি যে কোনও আবেদনকারীকে সাধারণীকরণ করে:

app :: (Applicative f, Applicative f1) => f (f1 (a -> b)) -> f (f1 a) -> f (f1 b)

তবে এর কোনও বুদ্ধিমান সংজ্ঞা নেই

join :: [Int -> [Int -> a]] -> [Int -> a]

আপনি যদি এটি সম্পর্কে স্বীকৃত না হন তবে এই অভিব্যক্তিটি বিবেচনা করুন:

join [\x -> replicate x (const ())]

পূর্বে কোনও পূর্ণসংখ্যার সরবরাহের পূর্বে অবশ্যই প্রত্যাবর্তিত তালিকার দৈর্ঘ্য প্রস্তর স্থাপন করতে হবে তবে সঠিক দৈর্ঘ্য প্রদত্ত পূর্ণসংখ্যার উপর নির্ভর করে। সুতরাং, joinএই ধরণের জন্য কোনও সঠিক ফাংশন উপস্থিত থাকতে পারে।


1
... সুতরাং কোন ফাংশন কখন করবে তা এড়াতে?
অ্যান্ড্রু কুক

2
@ অ্যান্ড্রু, যদি আপনি ফান্টেক্টর বোঝাতে চান তবে হ্যাঁ, ফান্ট্যাকারগুলি সহজতর এবং পর্যাপ্ত হলে ব্যবহার করা উচিত। মনে রাখবেন এটি সর্বদা না। উদাহরণস্বরূপ IOএকটি ছাড়া Monadপ্রোগ্রাম করা খুব কঠিন হবে। :)
রোটসর

17

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

রচনা মোনাড, http://web.cecs.pdx.edu/~mpj/pubs/RR-1004.pdf


4
অধৈর্য পাঠকদের জন্য টিএল; ডাঃ: আপনি প্রাকৃতিক রূপান্তর সরবরাহ করতে পারলে মোনাদ রচনা করতে পারেনswap : N M a -> M N a
আলেকজান্দ্রি সি

@ আলেকজান্দ্রে সি: আমি "সন্দেহ করি" কেবল "যদি", আমার সন্দেহ হয়। সমস্ত মোনাড ট্রান্সফর্মার সরাসরি ফান্টারের রচনা দ্বারা বর্ণনা করা হয় না। উদাহরণস্বরূপ, ContT r m aনা হয় m (Cont r a)না Cont r (m a)এবং StateT s m aমোটামুটি হয় Reader s (m (Writer s a))
সিএ ম্যাকক্যান

@ সিএ ম্যাকক্যান: আমি (এম মনাদ, এন মোনাড, এমএন মোনাড, এনএম মোনাড) থেকে (অদলবদল রয়েছে: এমএন -> এনএম প্রাকৃতিক) যেতে পারছি না। সুতরাং আপাতত "যদি" এর সাথে লেগে থাকি (সম্ভবত উত্তরটি কাগজে রয়েছে, আমি অবশ্যই তা দ্রুত দেখলাম তা স্বীকার করতে হবে)
আলেকজান্দ্রি সি

1
@ আলেকজান্দ্রি সি: কেবল উল্লেখ করে যে রচনাগুলি মনডগুলি যাইহোক পর্যাপ্ত পরিমাণে নাও হতে পারে - দুটি অংশ পুরোটির সাথে সম্পর্কিত করার জন্য আপনারও কিছু উপায় প্রয়োজন। এর অস্তিত্ব swapবোঝায় যে রচনাটি দুজনকে কোনওভাবে "সহযোগিতা" করতে দেয়। এছাড়াও, লক্ষ্য করুন যে sequenceএটি কিছু মনাদের জন্য "অদলবদল" একটি বিশেষ ক্ষেত্রে। সুতরাং হয় flipআসলে।
সিএ ম্যাকক্যান

7
swap :: N (M x) -> M (N x)এটি লিখতে আমার কাছে দেখে মনে হচ্ছে আপনি সামনের দিকে একটি সন্নিবেশ করানোর জন্য returns(যথাযথ fmapপ্যাড) ব্যবহার করতে পারেন Mএবং Nপিছন দিকে একটি সন্নিবেশ করানোর জন্য N (M x) -> M (N (M (N x))), তারপরে joinআপনার পাওয়ার জন্য যৌগিকটি ব্যবহার করুন M (N x)
পিগওয়ার্কার

7

বিতরণ আইন সমাধান l: MN -> NM যথেষ্ট

এনএম এর একাকীত্ব গ্যারান্টি এটি দেখতে আপনার একটি ইউনিট এবং একটি বহু প্রয়োজন need আমি বহু লোকের উপর ফোকাস করব (ইউনিটটি ইউনিট_ এন ইউনিটএম)

NMNM - l -> NNMM - mult_N mult_M -> NM

এটি গ্যারান্টি দেয় না যে এমএন একটি মোনাড।

গুরুত্বপূর্ণ পর্যবেক্ষণটি অবশ্য কার্যকর হয় যখন আপনার বিতরণ আইন সমাধান থাকে

l1 : ML -> LM
l2 : NL -> LN
l3 : NM -> MN

সুতরাং, এলএম, এলএন এবং এমএন হলেন ম্যানড। প্রশ্ন উঠেছে যে এলএমএন একটি মোনাদ কিনা (হয় দ্বারা)

(এমএন) এল -> এল (এমএন) বা এন (এলএম) -> (এলএম) এন দ্বারা

এই মানচিত্রগুলি তৈরি করার জন্য আমাদের পর্যাপ্ত কাঠামো রয়েছে। তবে, ইউজেনিয়া চেং যেমন পর্যবেক্ষণ করেছেন , উভয় নির্মাণের একাকীত্বের গ্যারান্টি দেওয়ার জন্য আমাদের একটি ষড়জাগরীয় অবস্থা (যা ইয়াং-বাক্সটার সমীকরণের উপস্থাপনের সমতুল্য) প্রয়োজন। আসলে, ষড়্ভুজীয় অবস্থার সাথে, দুটি পৃথক মনড মিলিত হয়।


9
এটি সম্ভবত একটি দুর্দান্ত উত্তর, কিন্তু এটা গিয়েছিলাম whoosh আমার মাথার উপর উপায়।
ড্যান বার্টন

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