Is there a free way to convert conditional check to Maybe type of input type?

I am just working on some simple exercises in haskell and wondering if there is a point way to convert the if-then-else statement to Maybe : Nothing if the condition is false, and Just enter if the condition is true.

In short, given some:

 maybeIf :: (a -> Bool) -> a -> Maybe a maybeIf cond a = if cond a then Just a else Nothing 

Is there an implementation that has no points for a ? I also looked at a more specific version of a -> Maybe a and feel that there might be an answer somewhere in Control.Arrow . However, since Maybe is a data type, and if-else statements control the flow of data, I'm not sure if there is a clean way to do this.

+5
source share
5 answers

You can import find from Data.Foldable , and then simply:

 import Data.Foldable(find) maybeIf cond = find cond . Just 

The find function is not complicated, so you can easily define it yourself less generically from the Maybe point of view, but it really is no different from your own maybeIf implementation, so you may not get much, depending on why you wanted to do this.

+7
source

The main thing to do for this point is if / then / else . You can define the if' combinator, or you can use this generic version, which I often define and use:

 ensure px = x <$ guard (px) 

Standard tools provide consistent, dissolute versions of both

 ensure p = ap (<$) (guard . p) ensure = ap (<$) . (guard .) 

although I really don't think this is better than the dotted version.

+6
source

If we choose code coding for Boolean languages ​​...

 truth :: Bool -> a -> a -> a truth True tf = t truth False tf = f 

Then we can write a point maybeIf in an applicative style.

 maybeIf :: (a -> Bool) -> a -> Maybe a maybeIf = liftA3 truth <*> pure Just <*> pure (pure Nothing) 

Some intuition ...

 f <$> m₁ <*> … <*> mβ‚™ = \x -> f (m₁ x) … (mβ‚™ x) liftAβ‚™ f <$> m₁ <*> … <*> mβ‚™ = \x -> f <$> m₁ x <*> … <*> mβ‚™ x 

Here is the PNG rendering of the above β€œintuitions” if your installed fonts do not support the desired Unicode character.

enter image description here

So therefore:

 liftA3 truth <*> pure Just <*> pure (pure Nothing) = liftA3 truth <$> id <*> pure Just <*> pure (pure Nothing) = \p -> truth <$> id p <*> (pure Just) p <*> (pure (pure Nothing)) p = \p -> truth <$> p <*> Just <*> pure Nothing = \p -> \a -> truth (pa) (Just a) ((pure Nothing) a) = \p -> \a -> truth (pa) (Just a) Nothing 
+3
source

Following the dfeuer lead (and using the new name Daniel Wagner for this function),

 import Data.Bool (bool) -- FT -- bool :: a -> a -> Bool -> a ensure :: (a -> Bool) -> a -> Maybe a ensure px = bool (const Nothing) Just (px) x ensure p = join (bool (const Nothing) Just . p) = bool (const Nothing) Just =<< p ensure = (bool (const Nothing) Just =<<) 

join is a monadic function join :: Monad m => m (ma) -> ma , but for functions it is simple

 join kx = kxx (k =<< f) x = k (fx) x 

join taken to replace W combinator in text code.

You only wanted it to be potential-free with respect to the value argument, but it easily transformed the equation with join further (readability of the result is another problem), since

  = join ((bool (const Nothing) Just .) p) = (join . (bool (const Nothing) Just .)) p 

Really,

  #> (join . (bool (const Nothing) Just .)) even 3 Nothing #> (bool (const Nothing) Just =<<) even 4 Just 4 
+2
source

This function is defined in Control.Monad.Plus and is called "partial"

0
source

Source: https://habr.com/ru/post/1239506/


All Articles