GHC's ViewPatterns
extension has a lot of unexpected uses. One that I've found recently is input validation.
{-# LANGUAGE ViewPatterns #-}
import Control.Monad
import Text.Printf
months :: [String]
months = words "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"
Using this function:
range :: (Ord a) => a -> a -> a -> a
range lb ub x
| (x < lb) || (x > ub) = error "argument out of range"
| otherwise = x
we can put bounds on arguments:
month :: Int -> String
month (range 1 12 -> m) = months !! (m-1)
like so:
GHCi> month 3
"Mar"
GHCi> month 15
"*** Exception: argument out of range
This version provides better error messages:
-- V for 'verbose'
rangeV :: (Ord a, Show a) => String -> a -> a -> a -> a
rangeV fun lb ub x
| (x < lb) || (x > ub) = error (printf msg fun (show x) (show lb) (show ub))
| otherwise = x
where msg = "%s: argument %s is outside of range [%s,%s]"
like so:
monthV :: Int -> String
monthV (rangeV "monthV" 1 12 -> m) = months !! (m-1)
GHCi> monthV 3
"Mar"
GHCi> monthV 15
"*** Exception: monthV: argument 15 is outside of range [1,12]
Or handle failure monadically:
-- Mp for MonadPlus
rangeMp :: (MonadPlus m, Ord a) => a -> a -> a -> m a
rangeMp lb ub x = guard ((x >= lb) && (x <= ub)) >> return x
like so:
monthMaybe :: Int -> Maybe String
monthMaybe (rangeMp 1 12 -> Just m) = Just (months !! (m-1))
monthMaybe _ = Nothing
GHCi> monthMaybe 3
Just "Mar"
GHCi> monthMaybe 15
Nothing
Yeah, that's nice. Personally I prefer the latter and would prefer it with Either so that you get actual information about why it failed.
ReplyDelete> {-# LANGUAGE ViewPatterns #-}
Supposing we use the Control.Applicative.Error class.
> import Control.Applicative.Error
And we define a function that ensures X is true:
> ensure :: String -> (a -> Bool) -> a -> Failing a
> ensure err p a
> | p a = Success a
> | otherwise = Failure [err]
We can then define inRange in terms of it for Failing:
> inRange :: (Show a,Ord a) => a -> a -> a -> Failing a
> inRange lb ub x = ensure err (\a -> a>=lb && a<=ub) x where
> err = "Must be in range >=" ++ show lb ++ " and <= " ++ show ub
And our `month' and `day' functions are defined like this:
> months :: [String]
> months = words "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"
> month :: Int -> Failing String
> month (inRange 1 12 -> Success m) = Success $ months !! (m-1)
> month _ = Failure ["Month must be in range 1-12."]
> days :: [String]
> days = words "Monday Tuesday Wednesday Thursday Friday Saturday Sunday"
> day :: Int -> Failing String
> day (inRange 1 7 -> Success d) = Success $ days !! (d-1)
> day _ = Failure ["Day must be in range 1-7."]
The nice thing is we get this for free:
λ> (,) <$> month 1 <*> day 3
Success ("Jan","Wednesday")
λ> (,) <$> month 1 <*> day 12
Failure ["Day must be in range 1-7."]
λ> (,) <$> month 24 <*> day 12
Failure ["Month must be in range 1-12.","Day must be in range 1-7."]
It kind of sucks to be building strings all the time, it'd be
nicer to have proper types to represent these invariants, e.g.
> data Prop a = OutOfRange a | Empty a | WrongSize a | InvalidFormat a | Ok a
Or something like that. I suppose throwing exceptions is faster
than creating intermediate data structures.
Nice idea! But I would like to see listed in your post the alternative without view patterns:
ReplyDeletemonth :: Int -> String
month i | inRange 1 12 i = months !! (i-1)
| otherwise = error "..."
inRange :: Ord a => a -> a -> a -> Bool
inRange lb ub x = x >= lb && x <= ub
(the blog will probably clobber indentation)
Thanks for the suggestions Chris, and for mentioning Control.Applicative.Error. It definitely includes a few things I reimplemented in a recent project; I'll want to switch over.
ReplyDeleteThis is one of the things I love about (GHC) Haskell: you can often simply create a clever new "pseudo-syntax" out of the blue!!
ReplyDeleteThis "range checking pattern" would be rigid syntax in most other languages. Here it's just something that emerges from the programming paradigm.
ReplyDeleteشركة مكافحة حشرات بالدمام 0590352700 ديكوريند
شركة مكافحة حشرات بالدمام
مكافحة الحشرات من الأشياء الواجب فعلها علي اتم وجه حتي نتجنب الامراض و الأوبه التي تسببها الحشرات .
و لحل مثل هذه المشكله لابد من اللجوء الي الشركات ذوي الخبره ، علي أن تكون متميزه في مكافحة الحشرات و طرق القضاء عليها .
و مما لا شك فيه أن أفضل شركة بالدمام هي شركة ديكوريند لمكافحة الحشرات .
لما تقدمه الشركه من خدمات و طرق فعاله للقضاء علي الحشرات بجميع أنواعها .
الشركه تعتمد علي العماله المدربه جيدا ، و المبيدات و الأجهزه الفعاله في القضاء علي مثل هذه الآفات الضاره.
شركة مكافحة حشرات بالدمام
شركة مكافحة حشرات بالدمام
أنواع الحشرات :
نتيجة لارتفاع درجة الحراره و نسبه الرطوبة في الدول العربيه ، تنتشر و تكثر الحشرات في كثير من المناطق و خاصة التي تطل علي المسطحات المائيه .
تؤدي تلك الآفات الضاره الي اصابه قاطني المنزل بالأمراض و شعورهم بعدم الراحه ، و تقوم أيضا بإتلاف المنتجات الغذائيه و الاثاث و الملابس .
و تتنوع انواع الحشرات كالآتي :
ذباب
بعوض
براغيث
نمل
صراصير
و غيرها الكثير
و لتنجب مثل هذه المشاكل و الأمراض و الأوبئه و المخاطر التي قد تصيب أطفالنا الصغار ، يجب القضاء علي مثل هذه الحشرات تماما و ذلك بالاستعانه بذوي الخبره .
شركة ديكوريند تتمتع بالخبره الكافيه للقضاء علي الحشرات بجميع أنواعها و أشكالها بإستخدام المعدات الجيده و العماله المدربه و المبيدات المتميزه .
لماذا شركة ديكوريند ؟
مما لاشك فيه أن أسعار شركة ديكوريند لا تقبل المنافسه اطلاقا ، لما تقدمه الشركه من خدمات جيده جدا في مقابل الأسعار التي تكون في متناول الجميع .
و تسعي الشركه دائما إلي تقديم أرقي و أفضل الخدمات ، التي ترضي جميع عملائنا الكرام ، فلا تتردد في الاتصال بنا .
اتصل الان : 0556043168 – 0590352700 شركة ديكوريند لمكافحة الحشرات بالدمام و جميع مناطق المملكة العربيه السعودية
من خدماتنا :
تنظيف فلل بالرياض
تنظيف موكيت بالرياض
تنظيف منازل بالرياض
تنظيف شقق بالرياض
تنظيف خزانات بالرياض
تنظيف مجالس بالرياض
شركة مكافحة حشرات بالدمام
ReplyDeleteشركة كشف تسربات المياه بالدمام
شركة نقل عفش بالدمام
شركة تخزين اثاث بخميس مشيط
شركة تخزين اثاث بخميس مشيط
ReplyDeleteصور سكس متحركه عنيفه
سكس محارم اخ ينيك امة واختة
افلام سكس
فيلم الاثاره والتشويق و اغراء- رغبة فتاة – للكبار فقط 2017 مترجم +18
This is my blog. Click here.
ReplyDeleteรวมเทคนิคเล่นสล็อตออนไลน์
Nice Blog. Thanks for sharing with us. Such amazing information.
ReplyDeleteOnly Blog
Guest Blogger
Guest Blogging Site
Guest Blogging Website
Guest Posting Site
يتم استخدام بعض طرق إبعاد الحمام مثل وضع الشباك و رفع الأسلاك الحديدية الصلبة ومنع الحمام من الوقوف في الحقل وتعتبر هذه الطريقة فعالة في طرد الحمام الموجود فوق اللوحات الإعلانية وكذلك تلك المعلقة على جدران المؤسسات والشركات الاعلانات التجارية. الشرائط ذات الألوان الزاهية يمكن استخدام الشرائط ذات اللون الأحمر أو الأصفر الفاتح لصد الحمام عن طريق لصق الحمام الذي يبلغ طوله نصف متر على جميع النوافذ أو على هذه النوافذ حيث يوجد الحمام. يمكن تحقيق طريقة العصا أو المسبحة هذه باستخدام خيط مسبحة طويل أو خيط مسبحة.لف الخيط حول الحمام ، مثل النافذة أو البلاط أو المنزل على السطح ، لتحقيق نتائج فعالة ، أكثر من سلسلة ، ويمكنك ربط ربطة عنق أو شريط على السلك ، الحمام طيور ذكية ، فإن ضربه بسلك محكم سيؤذيه ولن يعود ، بالإضافة إلى أن السلك المعلق سيخيفه.
ReplyDeleteشركة تركيب طارد الحمام بالمدينة المنورة
اسباب انتشار الحشرات
عدم الاهتمام بنظافة داخل المنزل وخارجه فلا بد من معرفة أن القمامة والربيع من أكبر العوامل المؤدية لوجود الحشرات وانتشارها.
تنبعث رائحة كريهة من المنزل بسبب تلف الأشياء أو القمامة القديمة أو التقشير المتروك لفترة طويلة.
فضح الطعام أو بقايا الطعام في المنزل لفترة طويلة.
إخراج الفاكهة من الثلاجة سيجذب الحشرات وخاصة الذباب.
توجد مياه راكدة في الإناء أو الأرضية لأن المياه الراكدة تنبعث منها رائحة تساعد على جلب الحشرات.
توجد حيوانات في المنزل ، خاصة إذا كانت مهملة ولا تنظف ولا ترش
الحشرات السامةا.
الحشرات من أكثر المخلوقات المزعجة التي يمكن أن تجدها في منزلك ، فهذه الحشرات يمكن أن تسبب العديد من الأمراض المختلفة.
شركة مكافحة حشرات بالمدينة المنورة
غالبًا ما تحتاج الأماكن الأكثر استخدامًا والأوساخ في المنزل إلى تنظيف الرخام والأرضيات والجدران وإزالة الزيت عن الجدران والأرضيات وتنظيف المطبخ سواء كان من الألمنيوم أو الخشب وتلميعه. ضعها وأعدها بأمان ، ويقوم الفريق بتنظيف الحوائط بمنظفات خاصة ، سواء كانت رخامية أو سيراميك ، أرضيات وأحواض مختلفة ، لإزالة الدهون والبقع والزيوت والأتربة ، وتلميعها جيدًا لجعلها تبدو جديدة كما هي ، مع منعها تلف
شركة تنظيف منازل بالمدينة المنورة
Gutt Websäit : Biodata
ReplyDeleteGutt Websäit : Zonahobisaya
Gutt Websäit : Zonahobisaya
Gutt Websäit : Zonahobisaya
Gutt Websäit : Zonahobisaya
Gutt Websäit : Zonahobisaya
Gutt Websäit : Zonahobisaya
Gutt Websäit : Zonahobisaya
It is imperative that we read blog post very carefully. I am already done it and find that this post is really amazing.
ReplyDelete