হাস্কেলের ত্রুটিগুলি জানার সবচেয়ে সহজ উপায়


22

আমি হাস্কেল শেখার জন্য কাজ করছি এবং আমি যে ফাংশনগুলি লিখি তাতে ত্রুটিগুলি মোকাবেলার তিনটি ভিন্ন উপায় পেয়েছি:

  1. আমি কেবল লিখতে পারি error "Some error message.", যা একটি ব্যতিক্রম ছুঁড়ে দেয়।
  2. আমি আমার ফাংশন রিটার্ন রাখতে পারি Maybe SomeType, যেখানে আমি যা ফিরতে চাই তা দিতে বা করতে সক্ষম হতে পারি।
  3. আমি আমার ফাংশন রিটার্ন রাখতে পারি Either String SomeType, যেখানে আমি কোনও ত্রুটি বার্তা বা যা আমাকে প্রথম স্থানে ফিরে আসতে বলা হয়েছিল তা ফিরে আসতে পারি।

আমার প্রশ্নটি: ত্রুটিগুলি মোকাবেলার কোন পদ্ধতিটি আমার ব্যবহার করা উচিত এবং কেন? প্রসঙ্গের উপর নির্ভর করে আমার কি বিভিন্ন পদ্ধতি করা উচিত?

আমার বর্তমান বোঝাপড়াটি হ'ল:

  • বিশুদ্ধরূপে কার্যকরী কোডে ব্যতিক্রমগুলি মোকাবেলা করা "কঠিন" এবং হাস্কেলের মধ্যে কেউ যতটা সম্ভব খাঁটিভাবে কার্যকরী রাখতে চায়।
  • Maybe SomeTypeফাংশনটি যদি ব্যর্থ হয় বা সফল হয় তবে ফিরে আসা হ'ল উপযুক্ত জিনিস (অর্থাত, এটি ব্যর্থ হওয়ার বিভিন্ন উপায় নেই )।
  • Either String SomeTypeকোনও ফাংশন বিভিন্ন উপায়ে যে কোনও একটিতে ব্যর্থ হতে পারলে ফিরে আসা সঠিক জিনিস do

উত্তর:


32

ঠিক আছে, হাসকেলে ত্রুটি পরিচালনা করার প্রথম নিয়ম: কখনই ব্যবহার করবেন নাerror

এটি প্রতিটি উপায়ে কেবল ভয়ঙ্কর। এটি ইতিহাসের একটি ক্রিয়াকলাপ হিসাবে বিশুদ্ধরূপে বিদ্যমান এবং প্রিলিড এটি ব্যবহার করে তা সত্যই ভয়ানক। এটি ব্যবহার করবেন না।

আপনি কেবলমাত্র এটি ব্যবহার করতে পারবেন যখন কোনও অভ্যন্তরীণভাবে এত ভয়াবহ হয় যে বাস্তবের খুব ফ্যাব্রিকের সাথে কোনও কিছু ভুল হতেই পারে, এইভাবে আপনার প্রোগ্রামের ফলাফলটি উপস্থাপন করতে পারে।

এখন প্রশ্ন Maybeবনাম হয়ে যায় EitherMaybeএটি এমন headকোনও কিছুর সাথে সুন্দরভাবে উপযুক্ত , যা কোনও মান প্রত্যাবর্তন করতে পারে বা নাও পারে তবে ব্যর্থ হওয়ার একমাত্র সম্ভাব্য কারণ রয়েছে। Nothing"এটি ভেঙে গেছে, এবং এর কারণ আপনি ইতিমধ্যে জানেন" এর মতো কিছু বলছে। কেউ কেউ বলবেন এটি একটি আংশিক ফাংশন নির্দেশ করে।

ত্রুটি পরিচালনার সর্বাধিক শক্তিশালী ফর্মটি হ'ল Either+ একটি ত্রুটি ADT।

উদাহরণস্বরূপ আমার শখের একটি সংকলকের মধ্যে আমার মতো কিছু রয়েছে

data CompilerError = ParserError ParserError
                   | TCError TCError
                   ...
                   | ImpossibleError String

data ParserError = ParserError (Int, Int) String
data TCError = CouldntUnify Ty Ty
             | MissingDefinition Name
             | InfiniteType Ty
             ...

type ErrorM m = ExceptT CompilerError m -- from MTL

এখন আমি একগুচ্ছ ত্রুটির ধরণগুলি সংজ্ঞায়িত করি, তাদের বাসা বেঁধে রাখি যাতে আমার একটি শীর্ষস্থানীয় ত্রুটি ত্রুটি থাকে। এটি সংকলনের কোনও পর্যায়ে বা একটি থেকে ত্রুটি হতে পারে ImpossibleError, যা একটি সংকলক বাগ চিহ্নিত করে if

এই ত্রুটির ধরণের প্রতিটি প্রিন্ট মুদ্রণ বা অন্যান্য বিশ্লেষণের জন্য যথাসম্ভব যতটা তথ্য রাখার চেষ্টা করে। আরও গুরুত্বপূর্ণ, স্ট্রিং না করে আমি পরীক্ষা করতে পারি যে টাইপ চেকারের মাধ্যমে একটি অসম্পূর্ণ প্রোগ্রাম চালানো আসলে একটি একীকরণ ত্রুটি তৈরি করে! একবার কিছু হয়ে গেলে Stringতা চিরতরে চলে যায় এবং এতে থাকা যে কোনও তথ্যই সংকলক / পরীক্ষাগুলির কাছে অস্বচ্ছ, সুতরাং কেবল Either Stringদুর্দান্ত নয়।

অবশেষে আমি ExceptTএমটিএল থেকে একটি নতুন মোনাড ট্রান্সফর্মার মধ্যে এই ধরণের প্যাক । এটি মূলত EitherTএবং শুদ্ধ, মনোরম উপায়ে ত্রুটিগুলি ছুঁড়ে ফেলার জন্য এবং ধরে রাখার জন্য একটি দুর্দান্ত ব্যাচের সাথে আসে।

অবশেষে, এটা মূল্য উল্লেখ করে Haskell, হ্যান্ডলিং ব্যতিক্রম সমর্থন করার জন্য মত অন্যান্য ভাষায় না, ছাড়া একটি ব্যতিক্রম জীবন সংক্রামক মেকানিজম রয়েছে IO। আমি জানি কিছু লোক IOভারী অ্যাপ্লিকেশনগুলির জন্য এগুলি ব্যবহার করতে পছন্দ করেন যেখানে সমস্ত কিছু সম্ভাব্যভাবে ব্যর্থ হতে পারে তবে এত কম সময়েই তারা এ সম্পর্কে ভাবতে পছন্দ করেন না। আপনি এই অপরিষ্কার ব্যতিক্রমগুলি ব্যবহার করেন বা ন্যায়সঙ্গত ExceptT Error IOসত্যই স্বাদের বিষয়। আমি ExceptTব্যর্থতার সম্ভাবনার কথা মনে করিয়ে দেওয়া পছন্দ করি বলে ব্যক্তিগতভাবে আমি নির্বাচন করি।


সংক্ষিপ্তসার হিসাবে,

  • Maybe - আমি এক সুস্পষ্ট উপায়ে ব্যর্থ হতে পারি
  • Either CustomType - আমি ব্যর্থ হতে পারি, এবং আমি আপনাকে বলব কী ঘটেছে
  • IO+ ব্যতিক্রম - আমি মাঝে মাঝে ব্যর্থ হই। আমি যখন করি তখন আমি কী নিক্ষেপ করি তা দেখতে আমার ডক্স পরীক্ষা করে দেখুন
  • error - আমি আপনাকে খুব ঘৃণা করি

এই উত্তরটি আমার জন্য অনেকটা পরিষ্কার করে দেয়। আমি নিজেকে অন্তর্নিহিত করেছিলাম যে বিল্ট-ইন ফাংশনগুলি ব্যবহার করার মতো headবা lastব্যবহারযোগ্য বলে মনে হচ্ছে error, তাই আমি ভাবছিলাম যে এটি আসলে জিনিসগুলি করার একটি ভাল উপায় এবং আমি কেবল কিছু মিস করছি। এই প্রশ্নের উত্তর। :)
CmdrMoozy

5
@CmdrMoozy খুশি সাহায্য করতে :) :) এটি সত্যিই দুর্ভাগ্য যে উপস্থাপিতের মতো খারাপ অভ্যাস রয়েছে। উত্তরাধিকারের এই পদ্ধতি: /
ড্যানিয়েল গ্রেটজার

3
+1 আপনার সারাংশ আশ্চর্যজনক
recursion.ninja

2

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

এর বাইরে, এটি তাত্ক্ষণিকভাবে আমার কাছে পরিষ্কার নয় যা Either String SomeTypeত্রুটির শর্ত তৈরি করতে পারে। আমি আরও একটি বর্ণনামূলক নাম সহ শর্তাবলী সহ একটি সাধারণ বীজগণিত ডেটা টাইপ করব।

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


আসলে, Eitherত্রুটিগুলির জন্য ব্যবহার করা হাস্কেলের একটি খুব সুপরিচিত প্যাটার্ন।
রাফলেউইন্ড

1
@rufflewind - Eitherএটি অস্পষ্ট অংশ নয়, Stringআসল স্ট্রিংয়ের চেয়ে ত্রুটি হিসাবে ব্যবহার করা ।
টেলাস্টিন

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