আমি স্ট্রিংকে কোনও টাইপক্লাসের উদাহরণ তৈরি করতে পারি না কেন?


85

প্রদত্ত :

data Foo =
  FooString String
class Fooable a where --(is this a good way to name this?)
  toFoo :: a -> Foo

আমি Stringএকটি উদাহরণ তৈরি করতে চাই Fooable:

instance Fooable String where
  toFoo = FooString

জিএইচসি তারপরে অভিযোগ করেছেন:

Illegal instance declaration for `Fooable String'
    (All instance types must be of the form (T t1 ... tn)
     where T is not a synonym.
     Use -XTypeSynonymInstances if you want to disable this.)
In the instance declaration for `Fooable String'

পরিবর্তে যদি আমি ব্যবহার করি [Char]:

instance Fooable [Char] where
  toFoo = FooString

জিএইচসি অভিযোগ করেছেন:

Illegal instance declaration for `Fooable [Char]'
   (All instance types must be of the form (T a1 ... an)
    where a1 ... an are type *variables*,
    and each type variable appears at most once in the instance head.
    Use -XFlexibleInstances if you want to disable this.)
In the instance declaration for `Fooable [Char]'

প্রশ্ন :

  • আমি স্ট্রিং এবং টাইপক্লাসের উদাহরণটি তৈরি করতে পারি না কেন?
  • যদি আমি অতিরিক্ত পতাকা যুক্ত করি তবে জিএইচসি আমাকে এখান থেকে সরিয়ে নিতে রাজি মনে হচ্ছে। এই একটি ভাল ধারণা?

6
এটি আমি এই জাতীয় প্রশ্নকে পছন্দ করে চিহ্নিত করেছি এবং পছন্দ হিসাবে চিহ্নিত করেছি কারণ অন্যথায় আমি জানি নিকট ভবিষ্যতে আমি এটি জিজ্ঞাসা করব;)
অস্কার মেডেরোস

4
অতিরিক্ত পতাকা সম্পর্কিত: যতক্ষণ আপনি জিএইচসির উপর নির্ভর করেন এবং পতাকাটি কী করে তা বুঝতে পারলে এটি সম্ভবত একটি ভাল ধারণা। ইয়েসোদ মাথায় আসে: ইয়েসোদ অ্যাপ্লিকেশনগুলি লেখার সময় ওভারলোডেড স্ট্রিংস প্রগমাটি সর্বদা ব্যবহার করতে আপনাকে উত্সাহ দেয় এবং কোয়েসিওকোটগুলি ইয়েসোদ রাউটিং বিধিগুলির একটি প্রয়োজনীয়তা। নোট করুন যে সংকলনের সময় পতাকার পরিবর্তে আপনি {-# LANGUAGE FlexibleInstances #-}আপনার .hh ফাইলের শীর্ষে (বা অন্য কোনও প্রগমা) রাখতে পারেন।
ড্যান বার্টন

উত্তর:


65

এ কারণে যে Stringজন্য মাত্র একটি টাইপ ওরফে [Char], যা শুধু টাইপ কন্সট্রাকটর প্রয়োগ []ধরনের উপর Char, তাই এই ফর্মের হবে ([] Char)। যা রূপের নয় (T a1 .. an)কারণ Charএটি কোনও ধরণের পরিবর্তনশীল নয়।

এই বিধিনিষেধের কারণ হ'ল ওভারল্যাপিং দৃষ্টান্তগুলি প্রতিরোধ করা। উদাহরণস্বরূপ, ধরা যাক আপনার একটি ছিল instance Fooable [Char]এবং তারপরে কেউ এসে আবার একটি সংজ্ঞায়িত করলেন instance Fooable [a]। এখন সংকলকটি আপনি কোনটি ব্যবহার করতে চেয়েছিলেন তা নির্ধারণ করতে সক্ষম হবে না এবং আপনাকে একটি ত্রুটি দেবে।

ব্যবহার করে -XFlexibleInstancesআপনি মূলত সংকলককে প্রতিশ্রুতি দিচ্ছেন যে আপনি এরকম কোনও উদাহরণ সংজ্ঞায়িত করবেন না।

আপনি কী অর্জন করতে চাইছেন তার উপর নির্ভর করে একটি মোড়কের সংজ্ঞা দেওয়া আরও ভাল:

newtype Wrapper = Wrapper String
instance Fooable Wrapper where
    ...

4
তর্ক করার পক্ষে বলতে দিন যে আমি সত্যই instance Fooable [a]চাইছিলাম। চর toFooথাকলে ফাংশনটি আলাদাভাবে আচরণ করার কোনও উপায় আছে a?
জন এফ মিলার

7
@ জন: একটি এক্সটেনশন রয়েছে -XOverlappingInstancesযা এটির অনুমতি দেবে এবং সুনির্দিষ্ট সুনির্দিষ্ট উদাহরণটি বেছে নেবে। বিশদ জন্য GHC ব্যবহারকারীর গাইড দেখুন
হামার

18

আপনি ক্লাসিক হাস্কেল ৯৮ টি টাইপ ক্লাসের দুটি সীমাবদ্ধতার মধ্যে চলেছেন:

  • উদাহরণস্বরূপ তারা টাইপ প্রতিশব্দটিকে অস্বীকার করে
  • তারা নেস্টেড টাইপগুলিকে বারণ করে না যা পরিবর্তিত ধরণের ভেরিয়েবলগুলি ধারণ করে না।

এই অত্যধিক নিষেধাজ্ঞাগুলি দুটি ভাষার বর্ধনের দ্বারা তোলা হয়েছে:

  • -XTypeSynonymInstances

যা আপনাকে টাইপ সিএনয়ামস (যেমন পছন্দ Stringকরে [Char]) এবং:

  • -XFlexibleInstances

যা T a b ..পরামিতিগুলি টাইপ ভেরিয়েবলগুলির ফর্মের উদাহরণস্বরূপ সীমাবদ্ধতাগুলি সরিয়ে দেয় । -XFlexibleInstancesপতাকা উদাহরণস্বরূপ ঘোষণার মাথা নির্বিচারে নেস্টেড ধরনের উল্লেখ করতে পারবেন।

মনে রাখবেন যে এই বিধিনিষেধগুলি তুলে নেওয়ার ফলে মাঝে মাঝে ওভারল্যাপিংয়ের উদাহরণ হতে পারে, সেই সময়ে দ্বিপাক্ষিকতা সমাধানের জন্য অতিরিক্ত ভাষা বর্ধনের প্রয়োজন হতে পারে, জিএইচসি আপনার জন্য উদাহরণ বেছে নিতে পারে pick


তথ্যসূত্র :


4

নমনীয় বিষয়গুলি বেশিরভাগ ক্ষেত্রে একটি ভাল উত্তর নয়। আরও ভাল বিকল্পগুলি স্ট্রিংটিকে একটি নতুন টাইপে মোড়ানো বা এর মতো সহায়ক সহায়ক শ্রেণি প্রবর্তন করা হয়:

class Element a where
   listToFoo :: [a] -> Foo

instance Element Char where
   listToFoo = FooString

instance Element a => Fooable [a] where
   toFoo = listToFoo

আরও দেখুন: http://www.haskell.org/haskellwiki/List_instance


2

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

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