سؤال

كود:

data Exp a = Const a | Eq (Exp a) (Exp a)

أريد Const a أن تحتوي على قيمة من نوع المعرض بحيث يمكن طباعتها في وقت لاحق.حتى في C# أود أن أكتب:

class Const : Exp { IShow X; }
class Eq : Exp { Exp X, Y; }

كيف يمكن أن أفعل ذلك في هاسكل ؟

هل كانت مفيدة؟

المحلول

{-# LANGUAGE GADTs #-}

data Exp a where
    Const :: Show a => a -> Exp a
    Eq :: Exp a -> Exp a -> Exp a

إذا كنت ترغب في السماح بفاخرة أنواع البيانات في فروع مختلفة من Eq هذا جيد أيضا

data Exp where
    Const :: Show a => a -> Exp
    Eq :: Exp -> Exp -> Exp

نصائح أخرى

يمكنك أن تفعل ذلك بقوله

data (Show a) => Exp a = Const a | Eq (Exp a) (Exp a)

ولكن هذا هو تقريبا دائما فكرة سيئة لأنه يفرض كل وظيفة يستخدم Exp ناهيك عن عرض القيد ، حتى لو لم يستخدم Show الأساليب.بدلا من ذلك, وضع العرض قيدا على وظائف إنها ذات الصلة.انظر العالم الحقيقي هاسكل للحصول على تفسير لذلك.

إذا كان كل ما تريد معرفته حول الحجة ل Const هل تستطيع ذلك show هذا، لماذا لا تخزن فقط الناتجة String القيمة في المنشئ بدلا من ذلك؟ علي سبيل المثال:

data Exp = Const String | Eq Exp Expr

example = Eq (Const (show 0)) (Const (show ""))

يشبه هذا عن كثب نسخة C #.

للإجابة على السؤال الثاني، طلب في التعليقات، Eq (Const 0) (Const "") غير قابل للتحقيق مع نوع البيانات لديك بسبب Exp Integer و Exp String ليسوا نفس النوع. خيار واحد هو القيام بشيء مثل

data Exp = forall a . Show a => Const a | Eq Exp Exp

سواء كان ذلك سيفعلك جيدا يعتمد على ما تخطط للقيام بهذه النوع.

تحرير: هذا يتطلب تمكين ملحقات اللغة كما هو مذكور.

أود أن أعلن فقط Datatype مثيل عرض فئة النوع:

data Exp a = Const a | Eq (Exp a) (Exp a)

instance (Show a) => Show (Exp a) where
    show (Const a) = show a
    show (Eq x y ) = "[ " ++ show x ++ " , " ++ show y ++ " ]"

انظر إلى ما يحدث عند تحميل هذا في GHCI وفعل:

*Main> let x = Eq (Const 1) (Eq (Const 2) (Const 3))
*Main> x      
[1 , [2 , 3] ]

الإجابة على التعليق:

يمكنك بسهولة التعامل مع أنواع مختلفة. لنفترض أنك تريد تحليل التعبيرات الرياضية. يمكنك الحصول على الهيكل التالي، على سبيل المثال:

data Expr  = Var String | Sum (Expr) (Expr) | Number Int | Prod (Expr) (Expr)

هذا يكفي لتمثيل أي تعبير مصنوع من مبالغ ومنتجات الأرقام والمتغيرات المسماة. علي سبيل المثال:

x = Sum (Var "x") (Prod (Number 5) (Var "y")) 

يمثل: X + 5Y

لطباعة هذا جميل سأفعل:

instance Show Expr where
    show (Var s) = show s
    show (Sum x y) = (show x) ++ " + " (show y)
    show (Prod x y) = (Show x) ++ (show y)
    show (Number x) = show x

هذا من شأنه أن يفعل الخدعة. يمكنك أيضا استخدام GADTS:

 data Expr where
      Var :: String -> Expr
      Sum :: Expr -> Expr -> Expr

إلخ ... ثم إنشاء هذا كما عرض.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top