হাসকেলে অন্তর্ভুক্ত, স্থির ধরণের কাস্ট (জবরদস্তি)


9

সমস্যা

হাস্কেলের নিম্নলিখিত নকশা সমস্যা বিবেচনা করুন। আমার একটি সাধারণ, প্রতীকী ইডিএসএল রয়েছে যাতে আমি ভেরিয়েবল এবং সাধারণ এক্সপ্রেশন (মাল্টিভারিয়েট পলিনোমিয়ালস) যেমন প্রকাশ করতে চাই x^2 * y + 2*z + 1। তদ্ব্যতীত, আমি অভিব্যক্তিগুলির উপর কিছু প্রতীকী সমীকরণ প্রকাশ করতে চাই, বলতে চাই x^2 + 1 = 1, পাশাপাশি সংজ্ঞাও পছন্দ করি x := 2*y - 2

লক্ষ্যটি হ'ল:

  1. ভেরিয়েবল এবং সাধারণ এক্সপ্রেশনগুলির জন্য পৃথক প্রকার রাখুন - নির্দিষ্ট ফাংশনগুলি ভেরিয়েবলগুলিতে প্রয়োগ করা যেতে পারে এবং জটিল এক্সপ্রেশন নয়। উদাহরণস্বরূপ, একজন সংজ্ঞা অপারেটর :=ধরনের হতে পারে (:=) :: Variable -> Expression -> Definitionএবং এটি একটি জটিল অভিব্যক্তি (যদিও এটা তার বাম দিকে প্যারামিটার হিসাবে পাস করা সম্ভব নাও হতে হবে উচিত , তার ডান দিকে প্যারামিটার হিসাবে একটি পরিবর্তনশীল পাস করা সম্ভব হতে স্পষ্ট ঢালাই ছাড়া ) ।
  2. অভিব্যক্তিগুলির একটি উদাহরণ রয়েছে Num, যাতে অভিব্যক্তিতে পূর্ণসংখ্যার লিটারালগুলি প্রচার করা সম্ভব হয় এবং কিছু অ্যাসিলিয়ারি র‌্যাপার অপারেটর প্রবর্তন না করে যোগ বা গুণনের মতো সাধারণ বীজগণিত ক্রিয়াকলাপগুলির জন্য একটি সুবিধাজনক স্বরলিপি ব্যবহার করা সম্ভব।

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

আলোচনা

এটি পরিষ্কার যে এখানে প্রধান সমস্যাটি হ'ল Numধরণের সীমাবদ্ধতা, যেমন

(+) :: Num a => a -> a -> a

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

উদাহরণ

আদর্শভাবে, আমি যেমন একটি লাইটওয়েট সিনট্যাক্স অর্জন করতে চাই

computation = do
  x <- variable
  t <- variable

  t |:=| x^2 - 1
  solve (t |==| 0)

বিশেষত, আমি স্বরলিপিটি নিষিদ্ধ করতে চাই, t + 1 |:=| x^2 - 1যেহেতু :=একটি চলক সংজ্ঞা দেওয়া উচিত এবং পুরো বাম দিকের এক্সপ্রেশন নয়।


1
হতে পারে আপনি class FromVar eকোনও পদ্ধতিতে কোনও ব্যবহার করতে পারেন fromVar :: Variable -> eএবং এর জন্য উদাহরণ সরবরাহ করতে পারেন Expressionএবং Variableতারপরে আপনার ভেরিয়েবলগুলিতে পলিমারফিক জাতীয় প্রকারগুলি x :: FromVar e => eথাকতে পারে I আমি এখনই আমার ফোনে থাকায় এটি কতটা ভাল কাজ করে তা পরীক্ষা করিনি have
মোড় এ।

FromVarটাইপক্লাস কীভাবে সহায়ক হবে তা আমি নিশ্চিত নই । আমি Exprউদাহরণ রেখে গিয়ে সুস্পষ্ট কাস্টস এড়াতে চাই Num। আমি প্রশ্নটি সম্পাদন করে একটি মুদ্রাক্ষর এর উদাহরণ যোগ করলাম যা আমি অর্জন করতে চাই।
ম্যাকিয়েজ বেনডকোভস্কি

উত্তর:


8

সাবটাইপিংয়ের পরিবর্তে পলিমারফিজম লাভ করার জন্য (কারণ আপনার কাছে হাস্কেলের মধ্যে এটিই রয়েছে), "ভেরিয়েবল একটি এক্সপ্রেশন" মনে করবেন না, তবে "ভেরিয়েবল এবং এক্সপ্রেশন উভয়েরই কিছু কার্য প্রচলিত রয়েছে"। এই অপারেশনগুলি একটি ধরণের শ্রেণিতে স্থাপন করা যেতে পারে:

class HasVar e where fromVar :: Variable -> e

instance HasVar Variable where fromVar = id
instance HasVar Expression where ...

তারপরে, জিনিসগুলি ingালাইয়ের পরিবর্তে জিনিসগুলিকে বহুমুখী করুন। আপনার যদি থাকে তবে v :: forall e. HasVar e => eএটি এক্সপ্রেশন এবং ভেরিয়েবল উভয়ই ব্যবহৃত হতে পারে।

example :: (forall e. HasVar e => e) -> Definition
example v = (v := v)  -- v can be used as both Variable and Expression

 where

  (:=) :: Variable -> Expression -> Definition

টাইপচেকের নীচে কোডটি তৈরি করতে কঙ্কাল: https://gist.github.com/Lysxia/da30abac357deb7981412f1faf0d2103

computation :: Solver ()
computation = do
  V x <- variable
  V t <- variable
  t |:=| x^2 - 1
  solve (t |==| 0)

মজার, ধন্যবাদ! আমি অল্পক্ষণের জন্য অস্তিত্বের ধরণের পিছনে উভয় ভেরিয়েবল এবং এক্সপ্রেশনকে আড়াল করে বিবেচনা করেছি, তবে আমি ধারণাটি প্রত্যাখ্যান করেছি কারণ এটি অতিরিক্ত স্বরলিপি প্রবর্তন করেছে, দেখুন আপনার V। প্রাথমিকভাবে এটি আমি যা চাইছিলাম তা নয়, তবে সম্ভবত আমি এটিকে খারিজ করতে খুব দ্রুত ছিলাম ... সম্ভবত আমি অস্বচ্ছ থেকে মুক্তি পেতে পারি না V। সম্পর্কিত নোটে, আমি কীভাবে একটি উদাহরণ তৈরি করতে পারি V (forall e . HasVar e => e)? কক-তে, আমি প্রকারভেদে টাইপ গণনা এবং প্যাটার্ন মিলটি ব্যবহার করতাম তবে হাস্কেলের মধ্যে কীভাবে এটি অর্জন করা যায় তা অস্পষ্ট।
ম্যাকিয়েজ বেনডকোভস্কি

1
আপনি একটি দখল করতে পারেন w :: Variableএকরকম এবং প্রয়োগ fromVarএটি: variable = (\w -> V (fromVar w)) <$> (_TODO_ :: Solver Variable)
লি-ইয়াও জিয়া ১৯

1
এবং Vঅবিশ্বাস্য প্রকারের সাথে এড়ানো যেতে পারে, তবে এটি এখনও ডাব্লুআইপি। অথবা আমরা variableএকটি বহুতল যুক্তির সাথে পরোক্ষভাবে পরিবর্তে পরিবর্তে স্পষ্ট করেই ধারাবাহিকতা নিতে পারি (>>=)
লি-ইয়াও জিয়া ১৯
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.