۲۰ - ۳تابع sequenceA
با چندتا مثال از sequenceA
شروع میکنیم، چون از traverse
سادهتره. از تایپ سیگنچرِش در بالا میبینید تأثیری که sequenceA
میذاره، جابجاییِ دو بافت (یا ساختار) با هم دیگهست. به خودیِخود امکانِ اعمال ِ تابع به a
رو نمیده؛ فقط جای لایههای ساختاری رو با هم عوض میکنه. اینها رو:
Prelude> sum [1, 2, 3]
6
Prelude> fmap sum [Just 1, Just 2, Just 3]
[1,2,3]
Prelude> (fmap . fmap) sum Just [1, 2, 3]
Just 6
Prelude> fmap product [Just 1, Just 2, Nothing]
[1,2,1]
با اینها مقایسه کنین:
Prelude> fmap Just [1, 2, 3]
[Just 1,Just 2,Just 3]
Prelude> sequenceA $ fmap Just [1, 2, 3]
Just [1,2,3]
Prelude> sequenceA [Just 1, Just 2, Just 3]
Just [1,2,3]
Prelude> sequenceA [Just 1, Just 2, Nothing]
Nothing
Prelude> fmap sum $ sequenceA [Just 1,Just 2,Just 3]
Just 6
Prelude> let xs = [Just 3, Just 4, Nothing]
Prelude> fmap product (sequenceA xs)
Nothing
اول با استفاده از sequenceA
ساختارها رو با هم جابجا کردیم – یعنی یه لیست از مقادیرِ Maybe
رو به یه Maybe
از لیستِ مقادیر تبدیل کردیم. در مثالهای بعد، یه تابع رو از روی ساختار ِ Maybe
لیفت کردیم و به لیستِ داخلش اعمال کردیم (البته اگه بعد از اعمال ِ sequenceA
به یه مقدارِ Just a
رسیده بودیم؛ چون مقادیرِ Nothing
لیستی برای اعمال شدن ندارن).
ارزش داره اشاره کنیم که ماژول ِ Data.Maybe
یه تابع به اسمِ catMaybes
داره که یه راه متفاوت برای کار با یه لیست از Maybe
ها ارائه میده:
Prelude> import Data.Maybe
Prelude> catMaybes [Just 1, Just 2, Just 3]
[1,2,3]
Prelude> catMaybes [Just 1, Just 2, Nothing]
[1,2]
Prelude> let xs = [Just 1, Just 2, Just 3, Nothing]
Prelude> sum $ catMaybes xs
6
Prelude> fmap sum $ sequenceA xs
Nothing
با استفاده از catMaybes
، حتی با وجودِ مقدار یا مقادیرِ Nothing
هم میشه بقیهی مقادیر رو پردازش کرد.