Haskell Map/Zip Vs. قائمة الفهم
-
02-10-2019 - |
سؤال
أي مما يلي أنت على الأرجح تكتب؟
r = zip xs $ map sqrt xs
أو
r = [(x, sqrt x) | x <- xs]
يبدو أن رمز العينة على الإنترنت يشير إلى أن الأول أكثر وفرة والطريقة المفضلة.
المحلول
من المحتمل أن أكتب
map (\x -> (x, sqrt x)) xs
إذا كنت تفضل خالية من النقاط ، فإن ما سبق يعادل (بعد الاستيراد Control.Monad
و Control.Monad.Instances
)
map (ap (,) sqrt) xs
بديل آخر لم يتم ذكره بعد
zipWith (,) xs (map sqrt xs)
نصائح أخرى
من المحتمل أن يكتب الأشخاص الذين يقضون الكثير من الوقت في #Haskell ذلك
r = map (id &&& sqrt) xs
(&&&)
هو combinator ممتع محدد في Control.Arrow
. توقيع نوعه الفعلي معقد لأنه معمم لجميع حالات السهم. لكنها تستخدم في كثير من الأحيان مع (->)
حالة Arrow
, مما يؤدي إلى توقيع هذا النوع:
(&&&) :: (a -> b) -> (a -> c) -> a -> (b, c)
على الرغم من أنني أميل إلى عدم استخدامها كثيرًا ، في هذه الحالة ، أعتقد أنني أفضل إصدار فهم القائمة ، لأنه يبدو أنظف بالنسبة لي.
إذا كنت في نمط خالي من نقطة ، فقد يعجبك هذا أيضًا:
f = zip `ap` map sqrt
يعيش AP في السيطرة. Monad وفي هذه الحالة ، يمكن اعتباره combinator ، الذي يعتمد على التطبيق في حساب التفاضل والتكامل التزلج:
ap f g x == f x (g x)
ap const const == id
كما يشير كونال ، قد يتم تعميم هذا أيضًا من موناد إلى التطبيق بالتطبيق (التحكم في الاستيراد.
f = zip <*> map sqrt
ربما أكتب map
/zip
وبعد ذلك أتمنى لو كنت قد كتبت فهم القائمة.
لأنواع معينة من المشاكل (مشروع أولر على وجه الخصوص) ، تظهر هذه الحالة بالذات في كثير من الأحيان لدرجة أنني كتبت المساعد الصغير التالي:
with :: (a -> b) -> a -> (a,b)
with f a = (a, f a)
هذا يسمح لكتابة مثالك:
r = map (with sqrt) xs
أنا أكثر من "مدرسة قديمة" Haskellier ، لذلك كنت أستخدم zip `ap` map sqrt
وبعد ذلك إعادة استخدامها لاستخدام <*>
بدلاً من ap
.
التطبيقي هو الموناد الجديد. (بمعنى "ماذا يستخدم أطفال هاسكل الرائع هذه الأيام؟")
نادراً ما أستخدم اختصارات قائمة ، لكن كلاهما هما. ما عليك سوى استخدام الكود الذي يجعل القراءة أسهل في الكود.