سؤال

instance Monad (Either a) where
     return = Left
     fail = Right
     Left x >>= f = f x
     Right x >>= _ = Right x

تسبب هذا الرمز في 'Baby.HS' في خطأ التجميع الرهيب:

Prelude> :l baby
[1 of 1] Compiling Main             ( baby.hs, interpreted )

baby.hs:2:18:
Couldn't match expected type `a1' against inferred type `a'
  `a1' is a rigid type variable bound by
       the type signature for `return' at <no location info>
  `a' is a rigid type variable bound by
      the instance declaration at baby.hs:1:23
In the expression: Left
In the definition of `return': return = Left
In the instance declaration for `Monad (Either a)'

baby.hs:3:16:
Couldn't match expected type `[Char]' against inferred type `a1'
  `a1' is a rigid type variable bound by
       the type signature for `fail' at <no location info>
  Expected type: String
  Inferred type: a1
In the expression: Right
In the definition of `fail': fail = Right

baby.hs:4:26:
Couldn't match expected type `a1' against inferred type `a'
  `a1' is a rigid type variable bound by
       the type signature for `>>=' at <no location info>
  `a' is a rigid type variable bound by
      the instance declaration at baby.hs:1:23
In the first argument of `f', namely `x'
In the expression: f x
In the definition of `>>=': Left x >>= f = f x

baby.hs:5:31:
Couldn't match expected type `b' against inferred type `a'
  `b' is a rigid type variable bound by
      the type signature for `>>=' at <no location info>
  `a' is a rigid type variable bound by
      the instance declaration at baby.hs:1:23
In the first argument of `Right', namely `x'
In the expression: Right x
In the definition of `>>=': Right x >>= _ = Right x
Failed, modules loaded: none.

لماذا يحدث هذا؟ وكيف يمكنني عمل هذا الرمز؟ شكرا على أي مساعدة ~

أنا أرى. وقمت بتعديل الكود لرؤيته يجمع:

instance Monad (Either a) where
     return = Right
     Left a >>= f = Left a
     Right x >>= f = f x

يجمع بنجاح! لكن ... لمزيد من السؤال:

instance Monad (Either a)

يجعل "إما" موناد وحصلت على "العودة = يمين" ... كيف يمكنني الحصول على "العودة = اليسار"؟ لقد جربت هذا ولكن فشلت:

instance Monad (`Either` a) where
     return = Left
     Right a >>= f = Right a
     Left x >>= f = f x

أو: مثيل monad ( x -> إما xa)

لا يجمع على الإطلاق!

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

المحلول

  1. يجب أن يكون للعودة نوع forall b. b -> Either a b, ومع ذلك اليسار له نوع forall c. a -> Either a c. ربما تريد هنا.
  2. fail يجب أن يكون النوع forall b. String -> Either a b, ومع ذلك ، فإن الصحيح له نوع forall b. b -> Either a b, ، حتى إذا b=String الذي يجعل String -> Either a String الذي لا يناسب.
  3. >>= يجب أن يكون النوع Either a b -> (b -> Either a c) -> Either a c ومع ذلك Right x >>= _ = Right x يعيد دائمًا قيمة النوع Either a b, ، ليس Either a c.
  4. Left x >>= f = f x لا يعمل لأن x له نوع a, ، لكن f لديه النوع b -> c.

نصائح أخرى

ينبع معظم الارتباك من الحقيقة اليسرى واليمين للخلف. بالنظر إلى نوع العودة فقط ، فإن نوعه من monad typeclass هو كما يلي:

return :: (Monad m) => b -> m b

أنت تحاول تحديد مثيل ل m = Either a, ، لذلك يجب أن يكون للعودة نوع:

return :: b -> Either a b

أنت تحددها على أنها اليسار ، والتي لها نوع:

Left :: a -> Either a b

لاحظ كيف الجانب الأيسر من -> يختلف.

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