سؤال

هل يمكن لأحد أن يشرح لي ، لماذا هذه الوظائف عدد مختلف من الحجج والسلوك, ، لكن ال نفس النوع توقيع, ، ومع ذلك فهي صحيحة؟

comp1 :: (a -> b) -> (b -> c) -> a -> c
comp1 f g = g.f

comp2 :: (a -> b) -> (b -> c) -> a -> c
comp2 f g x = g (f x)

أيضا ، لماذا لديها comp2

comp2 :: (a -> b) -> (b -> c) -> a -> c

بدلا من شيء مثل

comp2 :: a -> (a -> b) -> (b -> c) -> a -> c

?

شكرًا لك.

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

المحلول

comp2 f g x = g (f x)

هو السكر النحوي ل

comp2 = \f -> \g -> \x -> g (f x)

بصورة مماثلة

comp1 f g = g.f

هو السكر ل

comp1 = \f -> \g -> g.f

تعريف . هو:

f1 . f2 = \x -> f1 (f2 x) -- Names of arguments have been changed to avoid confusion

لذلك إذا أدخلت التعريف في الشكل Defuged من comp1, ، نحن نحصل:

comp1 = \f -> \g -> \x -> g (f x)

هذا هو بالضبط نفس الشكل Desugared من comp2, ، من الواضح أن التعاريف مكافئة.

نصائح أخرى

comp1 f g = g.f مكتوب في خالية من النقاط النمط (لا تشير إلى النقاط ، ولكن إلى القيم). عندما تتصل comp1, ، هناك ضمني معلمة ثالثة يتم تمريرها إلى g.f, ، وهو تكوين وظيفتين g و f: (g.f) x يساوي g (f x), ، بمعنى آخر g تم تمرير نتيجة f x. لا معلمة x موجود في comp1 لأنه ينتقل ضمنيًا إلى الوظيفة. (يمكنك التفكير في comp1 ك تطبيق جزئيا أو كاري الوظيفة إذا جعلك تشعر بتحسن.)

comp2نوع s يسأل عن وظيفتين ، واحدة من (a->b) وآخر (b->c), ، وكذلك معلمة من النوع a. ليست هناك حاجة لوضع a -> في توقيعها.

وظيفتان متكافئتان حقًا ؛ يستخدم المرء ببساطة بعض حيل هاسكل ليكون أكثر إيجازًا.

الكاري. وظيفة متعددة الحوائق في ML و Haskell ، هي مجرد سكر نحوي لوظيفة أحادية واحدة تُرجع وظيفة ؛ الوظيفة التي يعيدها تأخذ الحجج المتبقية.

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