يوصى بقراءة
المقال الأول إذا لم تكن قد قمت بذلك بالفعل. ستكون هذه المقالة أقصر وأقل تركيزًا على التفاصيل وأكثر على القدرات.
وفقا
لستيفن دييل ، جنبا إلى جنب مع أنواع التابعة ، وتجميع أسرع وعتبة دخول أقل ؛ الآثار الجبرية هي واحدة من أهم المهام التي سيتم حلها في المستقبل لهاسكل.
المستقبل ليس بعيدًا ، لذلك عليك أن تبدأ الآن.
رفع الآثار إلى آثار أخرى
class Liftable eff schema where lift :: eff ~> schema
ماذا يعني "رفع" في جوهرها؟
الرفع هو نفس
النقي /
العائد باستثناء أننا لا نغمر القيمة في التأثير ، ولكن التأثير في نوع من المحولات (في حالتنا ، في دائرة المحولات):
pure :: a -> ta lift :: ua -> tua
يتيح لنا ذلك استخدام أي تأثيرات داخل محول معين - من السهل تقديم تأثيرات جديدة ، لكننا سنحتاج لاحقًا إلى تفسير كل منها.
وبالتالي ، يمكننا أن نؤلف التأثيرات المرتفعة بأمان:
let f = lift get :: Configured _ t => t _ let g = lift Nothing :: Optional t => t _ let h = lift (failure _) :: Failable _ t => t _ let x = f *> g *> h :: (Applicative t, Configured _ t, Optional t, Failable _ t) => t _
وأرسلها بأي ترتيب مناسب لنا:
let y = pure _ :: Reader _ :> State _ :> Either _ :> Maybe := Int let z = pure _ :: State _ :> Either _ :> Maybe _ :> Reader := _ let x = f *> g *> h :: (Applicative t, Configured _ t, Optional t, Failable _ t) => t _ let xy = x *> y :: Reader _ :> State _ :> Either _ :> Maybe := _ let xz = x *> z :: State _ :> Either _ :> Maybe _ :> Reader := _
التكيف مع بعض الآثار للآخرين
class Adaptable subeff eff | subeff -> eff where adapt :: subeff ~> eff
التكيف يعني أنه يمكن استبدال بعض الآثار بتأثيرات أكثر قوة. على سبيل المثال ، يمكن استخدام تأثيرات
Reader و
Writer في
الحالة ، لأن
الحالة يمكنها القراءة والكتابة ، وبالتالي تغيير القيمة المخزنة:
lift put :: Accumulated _ t => t _ lift get :: Configured _ t => t _ (lift . adapt $ put) :: Stateful _ t => t _ (lift . adapt $ get) :: Stateful _ t => t _
كيف هذا ممكن؟ في المقال السابق ، قسمنا
الدولة إلى أثرين:
State s = (->) s :. (,) s
في حالة
Reader ، نرفع ببساطة سهم السهم إلى مستوى
الولاية ، وفي حالة
Writer ، فإن tuple functor:
Reader s = (->) s Writer s = (,) s
يمكننا تكييف
Failable مع
اختياري ، لكننا سنفقد معلومات الخطأ:
(lift $ Just _) :: Optional t => t _ (lift $ failure _) :: Failable _ t => t _ (lift . adapt $ failure _) :: Optional t => t _
تشغيل الآثار في المحولات
لتفسير تأثير في محول ، طريقة
تشغيل واحدة كافية:
let xy = x *> y :: Reader _ :> State _ :> Either _ :> Maybe := _ let xy' = run xy _ :: State _ :> Either _ :> Maybe := _ let xy'' = run xy' _ :: Either _ :> Maybe := _ let xy''' = run xy'' :: Maybe (Either _) _
الخلاصة والأمثلة
لذا ، الآن ، بدون monads حرة / مجانية (وأحيانًا حتى بدون monads) ، باستخدام
المفصل يمكنك كتابة تعبيراتك وفقًا للتأثيرات التي تنتجها. كل ما تحتاجه هو تكوين functor.
يوجد أيضًا
عرض تقديمي من تقرير حول هذا الموضوع في
التجمع المحلي في روستوف على نهر الدون ، والذي يمكن مشاهدته في المتصفح.
أفضل الأمثلة هي تلك الأقرب إلى الواقع قدر الإمكان. أحب الموسيقى ، حتى تتمكن من معرفة كيفية استخدام نظام التأثير هذا في
برنامج يقوم بتنزيل الألبومات من Bandcamp .