سؤال

في ما يجب أن تكون المواقف liftIO يستخدم؟ عندما أستخدم ErrorT String IO, ، ال lift تعمل الوظيفة على رفع تصرفات IO إلى ErrorT, ، لذا liftIO يبدو غير ضروري.

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

المحلول

lift يرفع دائمًا من الطبقة "السابقة". إذا كنت بحاجة إلى رفع من الطبقة الثانية ، فستحتاج lift . lift وهلم جرا.

من ناحية أخرى، liftIO يرفع دائمًا من طبقة IO (التي ، عند وجودها ، تكون دائمًا في أسفل المكدس). لذا ، إذا كان لديك أكثر من طبقتين من الموناد ، فستقدر liftIO.

قارن نوع الوسيطة في Lambdas التالية:

type T = ReaderT Int (WriterT String IO) Bool

> :t \x -> (lift x :: T)
\x -> (lift x :: T) :: WriterT String IO Bool -> T

> :t \x -> (liftIO x :: T)
\x -> (liftIO x :: T) :: IO Bool -> T

نصائح أخرى

Liftio هو مجرد اختصار لموناد IO ، أيا كان الموناد الذي أنت فيه. في الأساس ، يساوي Liftio استخدام عدد متغير من المصاعد. في البداية ، قد يبدو هذا زائداً عن الحاجة ، لكن استخدام Liftio له ميزة واحدة كبيرة: إنه يجعل رمز IO الخاص بك Indpendent من بناء الموناد الفعلي حتى تتمكن من إعادة استخدام نفس الرمز بغض النظر عند كتابة محول موناد).

على يد Ohter ، لا يأتي Liftio مجانًا ، كما يفعل Lift: يجب أن يكون المحولات Monad التي تستخدمها الدعم لها ، على سبيل المثال ، يجب أن تكون الموناد مثالًا على فئة Monadio ، ولكن معظم الموناد في الوقت الحاضر (وبالطبع ، سيقوم محقق النوع بفحص هذا لك في وقت الترجم: هذه هي قوة Haskell!).

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