اكتب خطأ أثناء محاولة تنفيذ وظيفة (>> =) من أجل إنشاء محول موناد مخصص

StackOverflow https://stackoverflow.com/questions/2661895

سؤال

أحاول إنشاء محول موناد لمشروع مستقبلي ، لكن لسوء الحظ ، لا يعمل تنفيذ وظيفة monad typeclasse (>> =).

بادئ ذي بدء ، إليك تطبيق Monad الأساسي:

newtype Runtime a = R { 
  unR :: State EInfo a
} deriving (Monad)

هنا ، يتم تنفيذ monad typeclasse تلقائيًا بواسطة GHC (باستخدام GeneralizedNewtypeDeriving لغة البراغما). يتم تعريف محول Monad على النحو التالي:

newtype RuntimeT m a = RuntimeT {
  runRuntimeT :: m (Runtime a)
} 

تأتي المشكلة من الطريقة التي أقوم بتأسيس وظيفة (>> =) من monad typeclasse:

instance (Monad m) => Monad (RuntimeT m) where
    return a = RuntimeT $ (return . return) a
    x >>= f =  runRuntimeT x >>= id >>= f

الطريقة التي أراها الأولى >>= يركض في الأساس m موناد. هكذا، runRuntimeT x >>= إرجاع قيمة النوع Runtime a (حقا ؟). ثم ، الرمز التالي ، id >>=, ، يجب إرجاع قيمة النوع a. هذه القيمة هي تم نقلها إلى وظيفة F من النوع f :: (Monad m) => a -> RuntimeT m b.

وهنا تأتي مشكلة النوع: f لا يتطابق نوع الوظيفة مع النوع المطلوب بواسطة دالة (>> =). جو هل يمكنني جعل هذا متماسك؟ أستطيع أن أرى لماذا هذا لا يعمل ، لكن لا يمكنني تحويله إلى شيء وظيفة.

تحرير: رسالة الخطأ:

Core.hs:34:4:
    Occurs check: cannot construct the infinite type: m = RuntimeT m
    When generalising the type(s) for `>>='
    In the instance declaration for `Monad (RuntimeT m)'
Failed, modules loaded: none.

شكرًا لك على المساعدة ، ولا تتردد في تصحيح أي عيوب في رسالتي ،
تشارلي ب.

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

المحلول

لمتابعة ما قاله ريد بارتون عن StateT - إليك كيف ستحددها RuntimeT استخدام StateT. ال Runtime يمكن بعد ذلك تحديد موناد بشكل تافهة باستخدام موناد الهوية.

newtype RuntimeT m a = R { 
  unR :: StateT EInfo m a
}

type Runtime = RuntimeT Identity

instance Monad m => Monad (RuntimeT m) where
    return = R . return

    (R m) >>= f = R (m >>= unR . f)

نصائح أخرى

المعتاد StateT s m موناد يرسل a إلى s -> m (a, s) لكنك تعمل مع m (s -> (a, s)) في حين أن. لا أعتقد أن هذا الأخير يشكل مونادًا للجنرال s. هل أنت متأكد من أنك لا تريد استخدامها فقط StateT?


هذا لماذا لا أعتقد am (s -> (a, s)) موناد: الكتابة >>= أحتاج إلى وظيفة تأخذ حجج الأنواع

m (s -> (a, s))
a -> m (s -> (b, s))

وإرجاع قيمة النوع

m (s -> (b, s))

"الآثار" (أي fmap (const ())) من النتيجة يجب أن تكون تلك الموجودة في الحجة الأولى ، حيث ليس لدينا طريقة للحصول على a لتمرير الحجة الثانية. حيث m يظهر فقط في الخارج من نوع النتيجة ، بعد ذلك لا يمكننا استخدام الوسيطة الثانية لأي شيء على الإطلاق - لن تكون هناك طريقة للتخلص من m يقدم.

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