Simplifying nested Maybe pattern matching

懵懂的女人 提交于 2019-12-04 13:42:40

UPDATED 2

Monad Either is for you

import Data.Maybe (maybe)

maybeE :: e -> Maybe a -> Either e a
maybeE e = maybe (Left e) Right

f :: Maybe (Maybe (Maybe d)) -> Either e d
f a  =   maybeE x a 
     >>= maybeE y
     >>= maybeE z

UPDATED 3

If we want to have not Either type, we could rewrite function:

import Data.Either(either)

either' = either id id

f :: Maybe (Maybe (Maybe d)) -> d
f a = either' $ maybeE x a 
            >>= maybeE y
            >>= maybeE z

Why did the code construct a Maybe (Maybe (Maybe X)) value in the first place? Unpacking such a value isn't nice, but the real question is, why there even is such a value. Maybe the code would better avoid all those nested Maybes.

If you really need to have such a value and need to do different things in all the Just/Nothing cases you'll have to write them all down. But instead of several nested case statements you could combine them into one big pattern match:

f Nothing                = x
f (Just Nothing))        = y
f (Just (Just Nothing))  = z 
f (Just (Just (Just d))) = d

Despite your constraint about not using maybe, I think this looks quite nice:

f = maybe x (maybe y (maybe z id))

or even better, as @pat suggests in his comment:

f = maybe x . maybe y . maybe z $ id
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!