سؤال

هذا الرمز يجمع بشكل جيد:

{-# 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.

الطريقة الوحيدة التي يمكنك من خلالها إصلاحها هي إعادة تشكيلها حتى لا تحتاجها بطريقة أو بأخرى.

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