হাস্কেল: <*> উচ্চারণ কীভাবে হয়? [বন্ধ]


109

আপনি কীভাবে প্রয়োগকর টাইপক্লাসে এই ফাংশনগুলি উচ্চারণ করেন:

(<*>) :: f (a -> b) -> f a -> f b
(*>)  :: f a -> f b -> f b
(<*)  :: f a -> f b -> f a

(এটি যদি অপারেটর না হয় তবে তাদের কী বলা হত?)

পার্শ্ব নোট হিসাবে, আপনি যদি pureঅ- গাণিতিকদের কাছে আরও বন্ধুত্বপূর্ণ কোনও নামকরণ করতে পারেন তবে আপনি এটি কী বলবেন?


6
@ জে কুপার ... আপনি কীভাবে এটি উচ্চারণ করবেন তা আপনি শুনতে সক্ষম হবেন? :) আপনি একটি ভয়েস রেকর্ডিং এবং প্লেব্যাক বৈশিষ্ট্যের জন্য মেটা.স্ট্যাকওভারফ্লো ডটকম এ একটি অনুরোধ পোস্ট করতে চাইতে পারেন :)।
কিরিল

8
এটি উচ্চারিত হয়েছে "শুভ দুঃখ, তারা আসলেই অপারেটরগুলির বাইরে চলেছিল, তাই না?" এছাড়াও, একটি ভাল নাম pureহতে পারে makeApplicative
চক

@ লিরিক, ঠিক আছে, আমি উচ্চারণ করে অনুমান করি আমার অর্থ "ওহাদ্দ্যা এই জিনিসটিকে কল করুন" :) @ চক, আপনার pureপরামর্শটি উত্তর হিসাবে পোস্ট করুন এবং আমি আপনাকে উজ্জীবিত করব
জে কুপার

6
(<*>) হ'ল কন্ট্রোল.অনেকশনাল সংস্করণ M মোনাডের "এপি", সুতরাং "এপি" সম্ভবত সবচেয়ে উপযুক্ত নাম।
এডওয়ার্ড কেএমইটিটি

11
আমি এটিকে একটি সাইক্লোপস বলব, তবে এটি কেবল আমার।
আরসিআইএক্স

উত্তর:


245

দুঃখিত, আমি সত্যিই আমার গণিত জানি না, তাই আমি আবেদনকারী টাইপক্লাসে কীভাবে ফাংশনগুলি উচ্চারণ করতে পারি তা আগ্রহী

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

Applicativeটাইপ শ্রেণীর মধ্যে কোথাও বসে Functorএবং Monad, তাই এক এটি একটি অনুরূপ গাণিতিক ভিত্তি আছে আশা করবে। Control.Applicativeমডিউলটির জন্য ডকুমেন্টেশন এর সাথে শুরু হয়:

এই মডিউলটি একটি ফান্টেক্টর এবং একটি মনাডের মধ্যে একটি কাঠামো মধ্যবর্তীটিকে বর্ণনা করে: এটি খাঁটি অভিব্যক্তি এবং সিকোয়েন্সিং সরবরাহ করে, তবে কোনও বাঁধাই করে না। (প্রযুক্তিগতভাবে, একটি শক্তিশালী শিথিল মনোফিডাল ফ্যাক্টর।)

হুম।

class (Functor f) => StrongLaxMonoidalFunctor f where
    . . .

Monadআমার মতো মনে হয় না তেমন আকর্ষণীয় ।

মূলত এই সমস্ত কিসের উত্সাহ তা হ'ল এটি Applicativeকোনও গাণিতিকভাবে বিশেষভাবে আকর্ষণীয় কোনও ধারণার সাথে মিলে না , সুতরাং হাস্কেলের ব্যবহারের উপায়ে ক্যাপচার কোনও শর্ত নেই around সুতরাং, আপাতত গণিতটি আলাদা করুন।


আমরা কী বলতে চাই তা জানতে চাইলে (<*>)এটির মূলত অর্থ কী তা জানতে সহায়তা করতে পারে।

তাই কি করে উঠে Applicativeযাই হোক, এবং কেন না আমরা যে কল?

কি Applicativeবাস্তবে পরিমাণ উত্তোলন একটি উপায় নির্বিচারে একটি মধ্যে ফাংশন FunctorMaybe(তর্কযোগ্যভাবে সহজতম তুচ্ছ Functor) এবং Bool(একইভাবে সরল অ-তুচ্ছ ডেটা টাইপের) সংমিশ্রণটি বিবেচনা করুন ।

maybeNot :: Maybe Bool -> Maybe Bool
maybeNot = fmap not

ফাংশনটি fmapআমাদের notকাজ করে কাজ করা Boolথেকে উঠতে দেয় Maybe Bool। কিন্তু যদি আমরা উত্তোলন করতে চাই (&&)?

maybeAnd' :: Maybe Bool -> Maybe (Bool -> Bool)
maybeAnd' = fmap (&&)

ওয়েল, এটা কি আমরা চাই না এ সব ! আসলে, এটি বেশ অযথা। আমরা চালাক হওয়ার চেষ্টা করতে পারি এবং অন্যটিকে পিছনের Boolদিকে লুকিয়ে দেখতে পারি Maybe...

maybeAnd'' :: Maybe Bool -> Bool -> Maybe Bool
maybeAnd'' x y = fmap ($ y) (fmap (&&) x)

... তবে এটি ভাল নয়। একটি জিনিস, এটি ভুল। অন্য একটি জিনিস, এটি কদর্য । আমরা চেষ্টা চালিয়ে যেতে পারতাম, তবে দেখা গেছে যে স্বেচ্ছায় কাজ করার জন্য একাধিক যুক্তি ফাংশন তুলতে পারে নাFunctor । বিরক্তিকর!

অন্যদিকে, আমরা যদি Maybeএর Monadউদাহরণ ব্যবহার করি তবে আমরা এটি সহজেই করতে পারতাম :

maybeAnd :: Maybe Bool -> Maybe Bool -> Maybe Bool
maybeAnd x y = do x' <- x
                  y' <- y
                  return (x' && y')

এখন, কেবল একটি সাধারণ ফাংশনটি অনুবাদ করার জন্য এটি অনেক ঝামেলা - যার কারণে Control.Monadএটি কোনও ফাংশন স্বয়ংক্রিয়ভাবে করার জন্য সরবরাহ করে liftM2। এর নামের ২ টি সত্যটি বোঝায় যে এটি ঠিক দুটি যুক্তির কাজ করে; 3, 4, এবং 5 টি যুক্তি ফাংশনের জন্য অনুরূপ ফাংশন বিদ্যমান। এই ফাংশনগুলি আরও ভাল , তবে নিখুঁত নয় এবং যুক্তিগুলির সংখ্যা উল্লেখ করা কুশ্রী এবং আনাড়ি।

যা আমাদের কাগজে এনে দেয় যা আবেদনকারী ধরণের শ্রেণি চালু করে । এতে লেখকরা মূলত দুটি পর্যবেক্ষণ করেন:

  • মাল্টি-আর্গুমেন্ট ফাংশনগুলিকে একটিতে তুলনা করা Functorখুব স্বাভাবিক জিনিস thing
  • এটি করার জন্য এ এর ​​সম্পূর্ণ ক্ষমতা প্রয়োজন হয় না Monad

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

এর সবকটিই আমাদের নীচের পয়েন্টে নিয়ে আসে: (<*>)কেবল ফাংশন অ্যাপ্লিকেশনকে উপস্থাপন করে - তবে কেন আপনি সাদা স্থান "জুস্টস্টেজেশন অপারেটর" এর চেয়ে আলাদাভাবে এটি উচ্চারণ করবেন?

তবে যদি এটি খুব সন্তোষজনক না হয় তবে আমরা পর্যবেক্ষণ করতে পারি যে Control.Monadমডিউলটি একটি ক্রিয়াও সরবরাহ করে যা মনাদের জন্য একই কাজ করে:

ap :: (Monad m) => m (a -> b) -> m a -> m b

কোথায় ap"প্রয়োগ" সংক্ষিপ্ত অবশ্যই, হয়। যেহেতু যে কোনও Monadহতে পারে Applicativeএবং apকেবলমাত্র পরবর্তী বৈশিষ্ট্যের উপসেট প্রয়োজন, তাই আমরা সম্ভবত এটি বলতে পারি যে অপারেটর না হলে (<*>)এটি কল করা উচিত ap


আমরা অন্য দিক থেকে জিনিসগুলির কাছেও যেতে পারি। Functorউত্তোলন অপারেশন বলা হয় fmapকারণ এটি একটি সাধারণীকরণ এর mapতালিকায় অপারেশন। তালিকাগুলিতে কি ধরণের ফাংশন কাজ করবে (<*>)? apতালিকাগুলিতে অবশ্যই যা আছে তা রয়েছে তবে এটি নিজস্বভাবে বিশেষ কার্যকর নয়।

আসলে, তালিকাগুলির জন্য সম্ভবত আরও একটি প্রাকৃতিক ব্যাখ্যা রয়েছে interpretation আপনি নিম্নলিখিত ধরণের স্বাক্ষরটি দেখলে কী মনে আসে?

listApply :: [a -> b] -> [a] -> [b]

সমান্তরালভাবে তালিকাগুলি রেখাযুক্ত করার ধারণা সম্পর্কে খুব লোভনীয় কিছু রয়েছে যা প্রথমটির প্রতিটি অংশটিকে দ্বিতীয়টির সাথে সম্পর্কিত উপাদানটিতে প্রয়োগ করে। দুর্ভাগ্যক্রমে আমাদের পুরানো বন্ধুর জন্য Monad, যদি তালিকাগুলি বিভিন্ন দৈর্ঘ্যের হয় তবে এই সাধারণ অপারেশনটি মানড আইন লঙ্ঘন করে । তবে এটি সূক্ষ্ম করে তোলে Applicative, এক্ষেত্রে একটি সাধারণ সংস্করণ একসাথে স্ট্রিংয়ের(<*>) একটি উপায় হয়ে যায় , তাই সম্ভবত আমরা এটি কল করার কল্পনা করতে পারি ?zipWithfzipWith


এই জিপিং ধারণাটি আসলে আমাদের পুরো বৃত্ত নিয়ে আসে। একাদিক ফান্টেক্টর সম্পর্কে, আগে এই গণিতের জিনিসগুলি মনে রাখবেন? নামটি যেমন বোঝায়, এগুলি মনোয়েড এবং ফান্টাক্টরের কাঠামোর সংমিশ্রনের একটি উপায়, যা উভয়ই পরিচিত হাস্কেল টাইপ শ্রেণি:

class Functor f where
    fmap :: (a -> b) -> f a -> f b

class Monoid a where
    mempty :: a
    mappend :: a -> a -> a

আপনি যদি তাদের একটি বাক্সে একসাথে রেখে কিছুটা ঝেড়ে ফেলেন তবে এগুলি দেখতে কেমন হবে? থেকে Functorআমরা একটি ধারণা করা চালিয়ে যাব এর ধরন প্যারামিটারের গঠন স্বাধীন থেকে, এবং Monoidআমরা ফাংশন সামগ্রিক ফর্ম যাব:

class (Functor f) => MonoidalFunctor f where
    mfEmpty :: f ?
    mfAppend :: f ? -> f ? -> f ?

আমরা একটি সত্যিকারের "খালি" তৈরি করার জন্য একটি উপায় আছে যে অনুমান করতে না চান Functor, এবং আমরা, একটি অবাধ ধরনের একটি মান ভেলকি দেখান আপ করতে পারবেন না তাই আমরা ধরণ ঠিক করব mfEmptyযেমন f ()

আমরা mfAppendএকটি সামঞ্জস্যপূর্ণ টাইপ পরামিতি প্রয়োজন জোর করতে চাই না , সুতরাং এখন আমাদের এটি আছে:

class (Functor f) => MonoidalFunctor f where
    mfEmpty :: f ()
    mfAppend :: f a -> f b -> f ?

ফলাফলের ধরন কী mfAppend? আমাদের দুটি স্বেচ্ছাচারী প্রকার রয়েছে যার সম্পর্কে আমরা কিছুই জানি না, তাই আমাদের কাছে অনেকগুলি বিকল্প নেই। সবচেয়ে বুদ্ধিমান জিনিস হ'ল উভয়কেই রাখা:

class (Functor f) => MonoidalFunctor f where
    mfEmpty :: f ()
    mfAppend :: f a -> f b -> f (a, b)

কোন পর্যায়ে mfAppendএখন স্পষ্টতই zipতালিকার সাধারণ সংস্করণ , এবং আমরা Applicativeসহজেই পুনর্গঠন করতে পারি:

mfPure x = fmap (\() -> x) mfEmpty
mfApply f x = fmap (\(f, x) -> f x) (mfAppend f x)

এটি আমাদের সনাক্ত করে যা pureএকটি এর সনাক্তকরণ উপাদানটির সাথে সম্পর্কিত Monoid, সুতরাং এর জন্য অন্যান্য ভাল নামগুলি কোনও ইউনিট মান, নাল অপারেশন, বা এর মতো কিছু হতে পারে suggest


এটি দীর্ঘ ছিল, তাই সংক্ষেপে:

  • (<*>) এটি কেবলমাত্র একটি পরিবর্তিত ফাংশন অ্যাপ্লিকেশন, সুতরাং আপনি এটিকে "এপি" বা "প্রয়োগ" হিসাবে পড়তে পারেন, বা এটি পুরোপুরিভাবে এলিডে ফাংশন অ্যাপ্লিকেশন হিসাবে ব্যবহার করতে পারেন।
  • (<*>)এছাড়াও zipWithতালিকাগুলিতে মোটামুটি সাধারণীকরণ করে, আপনি এটির সাথে "জিপ ফ্যান্টেক্টর" হিসাবে পড়তে পারেন, একইভাবে fmap"সাথে একটি ফান্টারের সাথে মানচিত্র" পড়তে পারেন ।

প্রথমটি Applicativeটাইপ শ্রেণীর উদ্দেশ্যটির কাছাকাছি - নামটি যেমন সুপারিশ করে - তাই এটিই আমি প্রস্তাব করি।

আসলে, আমি সমস্ত উত্তোলিত অ্যাপ্লিকেশন অপারেটরগুলির উদার ব্যবহার এবং অ-উচ্চারণকে উত্সাহিত করি :

  • (<$>), যা একটিতে একক যুক্তি ফাংশনটি উত্তোলন করে Functor
  • (<*>), যা একটি এর মাধ্যমে একটি বহু-যুক্তি ফাংশনকে শৃঙ্খলাবদ্ধ করে Applicative
  • (=<<), যা একটি ফাংশনকে আবদ্ধ করে যা Monadএকটি বিদ্যমান গণনাতে প্রবেশ করে

তিনটিই হ'ল, কেবল নিয়মিত ফাংশন অ্যাপ্লিকেশন, কিছুটা মশলাদার।


6
@ কলিন কোচরান: আপনি কি নিশ্চিত যে আপনি সেখানে "দীর্ঘ-বায়ু" ভুল বানান করেননি? :) তবে আরে আমি নেব! আমি সর্বদা এটি অনুভব করি Applicativeএবং এটি প্রচারিত ক্রিয়ামূলক অভিবাদনীয় শৈলীতে পর্যাপ্ত ভালবাসা পাওয়া যায় না, তাই আমি কীভাবে উচ্চারণ করি না (তা নয়) ব্যাখ্যা করার উপায় হিসাবে আমি এর গুণাবলীকে কিছুটা প্রশংসার সুযোগটি প্রতিরোধ করতে পারি না (<*>)
সিএ ম্যাকক্যান


6
হাস্কেলের কি সিনট্যাক্স চিনির দরকার ছিল Applicative! এর মতো কিছু [| f a b c d |](মূল কাগজ দ্বারা প্রস্তাবিত)। তারপরে আমাদের <*>সংযুক্তকারীটির প্রয়োজন হবে না এবং আপনি "ফান্টিক্যালের প্রসঙ্গে ফাংশন অ্যাপ্লিকেশন"
টম ক্রকেট

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

1
@pelotom: [দেখুন stackoverflow.com/questions/12014524/... যেখানে ধরনের মানুষ আমাকে প্রায় যে স্বরলিপি পেতে দুটি উপায়ে দেখিয়েছেন।
অ্যান্ড্রুসি

21

যেহেতু সিএ ম্যাকক্যানের প্রযুক্তিগত জবাবটি সম্পর্কে আমার উন্নতি করার কোন উচ্চাকাঙ্ক্ষা নেই , তাই আমি আরও বাড়াবাড়িটিকে মোকাবিলা করব:

আপনি যদি pureআমার মতো পোডঙ্কসের সাথে আরও বন্ধুত্বপূর্ণ কোনও নামকরণ করতে পারেন তবে আপনি কী ডাকবেন?

বিকল্প হিসাবে, বিশেষত যেহেতু Monad" return" নামক সংস্করণটির বিরুদ্ধে ধ্রুবক অ্যাংস্ট-এবং-বিশ্বাসঘাতকতা দ্বারা ভরা কান্নার কোনও শেষ নেই , আমি অন্য নামটির প্রস্তাব দিচ্ছি, যা এর ক্রিয়াকলাপটি এমনভাবে প্রস্তাব দেয় যা অত্যাবশ্যক প্রোগ্রামারদের সবচেয়ে অপরিহার্যকে সন্তুষ্ট করতে পারে এবং অধিকাংশ এর ... কার্মিক ভাল, আশা করছি, সবাই একই সম্পর্কে অভিযোগ করতে পারেন: inject

একটি মান নিন। বাক্সে "উদ্বুদ্ধ" এটা Functor, Applicative, Monad, বা কি-আছে-আপনি। আমি " inject" এর পক্ষে ভোট দিয়েছি এবং আমি এই বার্তাটি অনুমোদন করেছি।


4
আমি সাধারণত "ইউনিট" বা "লিফট" এর মতো কিছু দিকে ঝুঁকছি তবে হাস্কেলের মধ্যে ইতিমধ্যে এর অর্থ অনেক বেশি। injectএটি একটি দুর্দান্ত নাম এবং সম্ভবত আমার চেয়ে ভাল, যদিও একটি ছোটখাটো পার্শ্ব নোট হিসাবে, "ইনজেকশন" ব্যবহার করা হয়েছে - আমার মনে হয় - কোনও ধরণের বাম-ভাঁজ পদ্ধতির জন্য স্মলটালক এবং রুবি। নামটির পছন্দটি আমি কখনই বুঝতে পারি নি, যদিও ...
সিএ ম্যাকক্যান

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

1
করতে আবার পুরানো পার্শ্ব-থ্রেড কুড়ান: আপনি না অপারেটার ইনজেকশনের, আপনি (দূর) কনস্ট্রাকটর ইতিমধ্যে আছে প্রতিস্থাপন করছেন করছি। (অন্যান্য উপায় বৃত্তাকার দেখলে আপনি করছেন ইনজেকশনের একটি নতুন ধরনের পুরনো তথ্য।) তালিকার জন্য, বর্জন ঠিক হয় foldr। (আপনি প্রতিস্থাপন করেছেন (:)এবং []যেখানে (:)২ টি আরোগুলি লাগে এবং []এটি একটি ধ্রুবক, তাই foldr (+) 0 (1:2:3:[])1+2+3+0।) Boolএটি ঠিক if- then- else(দুটি ধ্রুবক, একটি বাছাই করুন) এবং এর জন্য Maybeবলা হয়েছে maybe... হাস্কেলের পক্ষে এর কোনও একক নাম / ফাংশন নেই, কারণ সকলের আলাদা আলাদা ধরন রয়েছে (সাধারণভাবে এলামটি কেবল পুনরাবৃত্তি / অন্তর্ভুক্তি)
কেউ

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

7

সংক্ষেপে:

  • <*>আপনি এটি প্রয়োগ কল করতে পারেন । তাই Maybe f <*> Maybe aউচ্চারিত করা যেতে পারে প্রয়োগ Maybe fউপরMaybe a

  • অনেক জাভাস্ক্রিপ্ট লাইব্রেরির মতো আপনিও এর নাম পরিবর্তন pureকরতে ofপারেন। জেএসে আপনি এর Maybeসাথে একটি তৈরি করতে পারেন Maybe.of(a)

এছাড়াও, হাস্কেলের উইকির ভাষা অপারেটরদের উচ্চারণের জন্য এখানে একটি পৃষ্ঠা রয়েছে


3
(<*>) -- Tie Fighter
(*>)  -- Right Tie
(<*)  -- Left Tie
pure  -- also called "return"

উত্স: ক্রিস অ্যালেন এবং জুলি মরোনুকির রচিত প্রথম নীতিগুলি থেকে হাস্কেল প্রোগ্রামিং


যতদূর আমি বলতে পারি সেই নামগুলি ঠিক তেমন ধরেনি।
dfeuer

@ ডিফিউয়ার পরবর্তী প্রজন্মের হাস্কেল্লারের জন্য অপেক্ষা করুন যা সেই বইটি তাদের প্রাথমিক শিক্ষার উপাদান হিসাবে ব্যবহার করছে।
ডিএমভিয়ানা

1
এটা হতে পারে. নামগুলি ভয়ঙ্কর, কারণ এর অর্থগুলির সাথে তাদের কোনও সংযোগ নেই।
dfeuer

1
@ ডিফিউয়ার, আমি কোথাও একটি ভাল সমাধান দেখতে পাচ্ছি না। "এপি" / "প্রয়োগ" "টাই ফাইটার" এর মতোই অস্পষ্ট। সবকিছুই ফাংশন অ্যাপ্লিকেশন। তবে, নীল থেকে আসা একটি নাম ব্যবহারের মাধ্যমে অর্থ অর্জন করতে পারে। "অ্যাপল" একটি ভাল উদাহরণ। উপায় দ্বারা, একসংখ্যা আগমন হয় আবেদন বিশুদ্ধ। এখানে কোন আবিষ্কার নেই।
ডিএমভিয়ান
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.