۲۰ - ۸همههای کارها رو انجام بده
اینجا از یه کتابخونه ِ کلاینت ِ HTTP به اسم wreq استفاده میکنیم تا به یه وبسایتِ بهدردبخور برای تست ِ کلاینتهای HTTP به آدرسِ http://httpbin.org/ درخواست بدیم. هر آزمایشی دوست داشتین باهاش انجام بدین؛ اگر هم ایدهای داشتین، کُد رو تغییر بدین:
module HttpStuff where
import Data.ByteString.Lazy hiding (map)
import Network.Wreq
-- ،اگه دوست یا لازم داشتین
-- .آدرس وبسایت رو عوض کنین
urls :: [String]
urls = [ "http://httpbin.org/ip"
, "http://httpbin.org/bytes/5"
]
mappingGet :: [IO (Response ByteString)]
mappingGet = map get urlsولی اگه بجای یه لیست از اجراییههای IO که اجرای هرکدوم یه پاسخ میده، یه اجراییه ِ IO ِ بزرگ بخوایم که یه لیست از پاسخها درست میکنه چطور؟ اینجا میشه از Traversable استفاده کرد:
traversedUrls :: IO [Response ByteString]
traversedUrls = traverse get urlsامیدواریم با این مثالها متوجهِ مفید بودنِ تایپکلاسِ Traversable شده باشین. با اینکه Foldable به نظر پیشوپاافتاده میاد، اما یه سوپرکلاس ِ واجب برای Traversable ِه، و امروزه دیگه Traversable هم، مثل Functor و Monad، به خاطرِ کاربردی بودنش در هسکلنویسیِ روزمره استفاده میشه.
درکِ قدرتِ بیشتر
Traversable از Functor و Foldable قویتره، به همین خاطر میشه از Traversable به Functor و Foldable رسید، همونطور که میشه از Monad به Functor و Applicative رسید. در مثالِ زیر با استفاده از تایپِ Identity، تابعِ fmap رو بازسازی کردیم:
λ> import Data.Functor.Identity
λ> traverse (Identity . (+1)) [1, 2]
Identity [2,3]
λ> runIdentity $ traverse (Identity . (+1)) [1, 2]
[2,3]
λ> :{
λ| let edgeMap f t = runIdentity $
λ| traverse (Identity . f) t
λ| :}
λ> :t edgeMap
edgeMap :: Traversable t => (a -> b) -> t a -> t b
λ> edgeMap (+1) [1..5]
[2,3,4,5,6]با استفاده از Const یا Constant هم میشه یه تابعی شبیهِ foldMap از Foldable رو بدست آورد:
λ> import Data.Monoid
-- `transformers` از
λ> mport Data.Functor.Constant
λ> let xs = [1, 2, 3, 4, 5] :: [Sum Integer]
λ> traverse (Constant . (+1)) xs
Constant (Sum {getSum = 20})
λ> :{
λ| let foldMap' f t =
λ| getConstant $ traverse (Constant . f) t
λ| :}
λ> :t foldMap'
foldMap' :: (Traversable t, Monoid a)
=> (a1 -> a) -> t a1 -> a
λ> :t foldMap
foldMap :: (Foldable t, Monoid m)
=> (a -> m) -> t a -> mبا انجامِ چنین تمرینهایی درکتون از رابطهی بین این تایپکلاسها و تابعهای کانونیکِشون بیشتر میشه. قبول داریم که اینها ممکنه به نظر بیشتر از تمرین نباشن، اما نهایتاً چنین تسلطی در بازی با توابعه که آدم رو به هسکل مسلط میکنه.