مشكلة عند خلط الفصول الدراسية واكتب العائلات
-
25-09-2019 - |
سؤال
هذا الرمز يجمع بشكل جيد:
{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances,
UndecidableInstances, FlexibleContexts, EmptyDataDecls, ScopedTypeVariables,
TypeOperators, TypeSynonymInstances, TypeFamilies #-}
class Sel a s b where
type Res a s b :: *
instance Sel a s b where
type Res a s b = (s -> (b,s))
instance Sel a s (b->(c,a)) where
type Res a s (b->(c,a)) = (b -> s -> (c,s))
ولكن بمجرد أن أضيف REST FAIL GHC:
{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances,
UndecidableInstances, FlexibleContexts, EmptyDataDecls, ScopedTypeVariables,
TypeOperators, TypeSynonymInstances, TypeFamilies #-}
class Sel a s b where
type Res a s b :: *
instance Sel a s b where
type Res a s b = (s -> (b,s))
class R a where
type Rec a :: *
cons :: a -> Rec a
elim :: Rec a -> a
instance Sel a s (b->(c,Rec a)) where
type Res a s (b->(c,Rec a)) = (b -> s -> (c,s))
يشكو من ذلك:
Illegal type synonym family application in instance:
b -> (c, Rec a)
In the instance declaration for `Sel a s (b -> (c, Rec a))'
ماذا يعني و (الأهم من ذلك) كيف يمكنني إصلاحه؟
شكرًا
المحلول
نوع العائلات في اتجاه واحد: يمكنك التوسع Rec a
إلى نوعه المحسوب ، لكن لا يمكنك (بشكل فريد) الانتقال من التوسع إلى Rec a
. هذا يجعل تطبيقات وظائف النوع غير مناسبة على سبيل المثال توقيعات ، حيث لا يمكن أن تؤدي أبدًا إلى تشغيل المثيل.
يمكنك المحاولة بدلاً من ذلك:
instance Rec a ~ reca => Sel a s (b->(c,reca))
هذا يعني شيئًا آخر: إنه يقول أي وظيفة b -> (c, reca)
هو مثيل ، وبعد ذلك عندما يكون مطابقة بشكل لا رجعة فيه ، يتحقق المترجم Rec a ~ reca
. ولكن قد يكون هذا جيدًا بما يكفي للقيام به في قضيتك.
نصائح أخرى
Rec
ليس مُنشئًا نوعًا ؛ إنها وظيفة النوع. ربما يمكنك استخدامه فقط في نوع قيمة تعريف النوع ، وليس في إعلان الفصل؟ أنا أخمن هنا بعنف. لا أفهم جميع القواعد الخاصة بالعائلات.
لا أعرف كيفية إصلاحه ، لكن بعض الأشياء التي يجب تجربتها تشمل:
تخلص من الفصل SEL وتحديد فقط
type family Res a s b :: *
. يستخدمtype instance
بدلا من آلية الفصل.بالكاد من الممكن أن يصنع النوع
Rec
حقن باستخدامdata
سوف يساعد ، لكنني لا أعتقد ذلك.التراجع إلى أصغر عدد من ملحقات اللغة التي يمكن أن تعمل - سيسهل على الآخرين مساعدتك ، وقد تساعد المترجم أيضًا.
هذا يعني أنه لا يُسمح لك باستخدام أسر نوع Synomym عند إعلان مثيلات النوع. انظر القسم "اكتب العائلات وإعلانات مثال" دليل GHC.
الطريقة الوحيدة التي يمكنك من خلالها إصلاحها هي إعادة تشكيلها حتى لا تحتاجها بطريقة أو بأخرى.