سؤال

ووفقا ل وTypeclassopedia (وبين مصادر أخرى)، Applicative ينتمي منطقيا بين Monad وPointed (وبالتالي Functor) في التسلسل الهرمي نوع الطبقة، لذلك سيكون لدينا مثالي شيئا من هذا القبيل إذا كانت مكتوبة تمهيدا هاسكل اليوم:

class Functor f where
    fmap :: (a -> b) -> f a -> f b

class Functor f => Pointed f where
    pure :: a -> f a

class Pointed f => Applicative f where
    (<*>) :: f (a -> b) -> f a -> f b

class Applicative m => Monad m where
    -- either the traditional bind operation
    (>>=) :: (m a) -> (a -> m b) -> m b
    -- or the join operation, which together with fmap is enough
    join :: m (m a) -> m a
    -- or both with mutual default definitions
    f >>= x = join ((fmap f) x)
    join x = x >>= id
    -- with return replaced by the inherited pure
    -- ignoring fail for the purposes of discussion

و(حيث أعيد كتابتها، تلك التعريفات الافتراضية التي كتبها لي من تفسير في ويكيبيديا أو أخطاء يجري بلدي، ولكن إذا كان هناك أخطاء فهي على الأقل من حيث المبدأ ممكن).

وكما تم تعريفها في المكتبات حاليا، لدينا:

liftA :: (Applicative f) => (a -> b) -> f a -> f b
liftM ::       (Monad m) => (a -> b) -> m a -> m b

وو:

(<*>) :: (Applicative f) => f (a -> b) -> f a -> f b
ap    ::       (Monad m) => m (a -> b) -> m a -> m b

لاحظ التشابه بين هذه الأنواع ضمن كل زوج.

وسؤالي هو: هل liftM (تمييزا لها عن liftA) وap (تمييزا لها عن <*>)، مجرد نتيجة للواقع التاريخي الذي Monad لم يصمم مع Pointed وApplicative في الاعتبار؟ أم أنها في بعض الطريق السلوكية الأخرى (يحتمل أن تكون، بالنسبة لبعض التعاريف Monad القانونية) تختلف عن النسخ التي لا تتطلب سوى سياق Applicative؟

إذا أنها تختلف، هل يمكن أن توفر مجموعة بسيطة من التعاريف (طاعة القوانين المطلوبة من Monad، Applicative، Pointed، وتعريفات Functor موضح في Typeclassopedia وأماكن أخرى ولكن لم يطبق من قبل النظام نوع) التي liftA وliftM تتصرف بشكل مختلف؟

وبدلا من ذلك، إذا لم تكن متميزة، يمكن أن تثبت معادلتها تستخدم تلك القوانين نفس المبنى؟

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

المحلول

وliftA، liftM، fmap، و. <م> يجب يكون كل نفس الوظيفة، وأنها <م> يجب يكون إذا استيفائها للقانون functor:

fmap id = id

ولكن، هذا لا فحصها من قبل هاسكل.

والآن لتطبيقية. فمن الممكن لap و<*> لتكون متميزة عن بعض [فونكتورس] لأنه ببساطة يمكن أن يكون هناك تنفيذ أكثر من واحد الذي يرضي أنواع والقوانين. على سبيل المثال، قائمة تضم أكثر من واحد ممكن المثال Applicative. هل يمكن أن تعلن تطبيقية على النحو التالي:

instance Applicative [] where
  (f:fs) <*> (x:xs) = f x : fs <*> xs
  _      <*> _      = []
  pure              = repeat

وسيظل تعريف الدالة ap كما liftM2 id، وهو المثال Applicative التي تأتي مجانا مع كل Monad. ولكن هنا لدينا مثال من نوع منشئ وجود سبيل المثال Applicative أكثر من واحد، وكلاهما تلبية القوانين. ولكن إذا الكائنات الدقيقة الاحاديه الخلية و[فونكتورس] تطبيقية الخاص بك لا يوافقون، وانها تعتبر شكل جيد لدينا أنواع مختلفة لهم. على سبيل المثال، والمثال Applicative أعلاه لا يتفق مع الكائن الدقيق الاحادي الخلية ل[]، لذلك ينبغي أن أقول لكم حقا newtype ZipList a = ZipList [a] ثم جعل مثيل جديد لZipList بدلا من [].

نصائح أخرى

<إنهم م> يمكن تختلف، لكنها <م> لا ينبغي أن .

ويمكن أن تختلف لأنها يمكن أن يكون لها تطبيقات مختلفة: تعريف واحد في instance Applicative بينما يتم تعريف البعض في instance Monad. ولكن إذا كانت تختلف في الواقع، ثم أود أن أقول مبرمج الذي كتب تلك الحالات كتب مضللة التعليمات البرمجية.

وأنت على حق: وجود وظائف كما يفعلون لأسباب تاريخية. الناس لديهم أفكار قوية حول كيف ينبغي أن يكون الأشياء.

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