Get the value out of Just constructor [duplicate] - haskell

I have a function that has a return type of Maybe ([(Int,Int)],(Int,Int))
I would like to call this from another function and perform an operation on the data.
However, the return value is contained within Just. The second method takes ([(Int,Int)],(Int,Int)) and therefore will not accept Just ([(Int,Int)],(Int,Int)).
Is there a way I can trim the Just before applying the second method?
I don't fully understand the use of Just within Maybe - however, I have been told that the return type for the first Method must be Maybe.

There are several solutions to your problem, all based around pattern matching. I'm assuming you have two algorithms (since you didn't name them, I will):
algorithm1 :: a -> Maybe b
algorithm2 :: b -> c
input :: a
1) Pattern matching is typically done from either a case statement (below) or a function.
let val = algorithm1 input
in case val of
Nothing -> defaultValue
Just x -> algorithm2 x
All other presented solutions use pattern matching, I'm just presenting standard functions that perform the pattern matching for you.
2) The prelude (and Data.Maybe) have some built-in functions to deal with Maybes. The maybe function is a great one, I suggest you use it. It's defined in standard libraries as:
maybe :: c -> (b -> c) -> Maybe b -> c
maybe n _ Nothing = n
maybe _ f (Just x) = f x
Your code would look like:
maybe defaultValue algorithm2 (algorithm1 input)
3) Since Maybe is a functor you could use fmap. This makes more sense if you don't have a default value. The definition:
instance Functor Maybe where
fmap _ Nothing = Nothing
fmap f (Just a) = Just (f a)
So your code would look like:
fmap algorithm2 (algorithm1 input)
This output will be a Maybe value (Nothing if the result of algorithm1 is Nothing).
4) Finally, and strongly discouraged, is fromJust. Only use it if you are positive the first algorithm will return Just x (and not Nothing). Be careful! If you call fromJust val when val = Nothing then you get an exception, which is not appreciated in Haskell. Its definition:
fromJust :: Maybe b -> b
fromJust Nothing = error "Maybe.fromJust: Nothing" -- yuck
fromJust (Just x) = x
Leaving your code to look like:
algorithm2 (fromJust (algorithm1 input))

You're looking for fromJust. But only if you're certain your Maybe function is not going to return a Nothing!

Related

Return an empty object of a certain type in Haskell

Here is what I am trying to do:
justExpose :: Maybe a -> a
justExpose (Just x) = x
justExpose Nothing = -- an empty object of type a
Any ideas?
In case your type a has monoid structure in it, then you can use this:
import Data.Monoid
justExpose :: Monoid a => Maybe a -> a
justExpose (Just x) = x
justExpose Nothing = mempty
Some examples of this:
λ> let x = Nothing :: Maybe (Sum Int)
λ> justExpose x
Sum {getSum = 0}
λ> justExpose (Just [])
[]
But you should note that Maybe type is very useful in lots of situations.
The Maybe a is the standard "type with empty value".
The way to extract that a is to perform a case-split or (better) use a
fromMaybe :: a -> Maybe a -> a -- Defined in ‘Data.Maybe’
function, which is declared as
fromMaybe :: a -> Maybe a -> a
fromMaybe def optional =
case optional of
Just value -> value
Nothing -> def
So, you just need to import Data.Maybe and call fromMaybe with an appropriate "empty object" of your choice (or what the task's domain requires there).
You can also leave it as Maybe a or even start to work in the Maybe monad, if you have many a -> Maybe b actions in the domain; the question here is the reason behind your "How do I...".
What you are asking for is a "null" in many other languages. Haskell deliberately does not provide such a thing, because it is unsafe.
You can get the code to compile as follows:
justExpose :: Maybe a -> a
justExpose (Just x) = x
justExpose Nothing = undefined
but if you call it with a Nothing you will get a runtime exception, because the value is, as the name suggests, undefined!
Update: As several people have pointed out, this functionality is provided by Data.Maybe.fromJust, as you can find by searching hoogle for your type signature Maybe a -> a
There is no such thing as an "empty object of a certain type" in Haskell (the gruesome "null" from various other languages). This is a necessity for type safety. If you ever want an "empty value" you are required to use Maybe.
There is however a thing known as ⊥ ("bottom"), which in some ways similar but not really the same thing. Every type has ⊥ as a possible value. Bottom manifests itself in several ways: typically as an error or as an infinite loop. For example, the following function yields bottom:
f x = f (x + 1)
This function will never return because it will loop indefinitely, and hence it's value is ⊥. Or you can raise an error:
justExpose :: Maybe a -> a
justExpose Nothing = error "there is Nothing"
But keep in mind such an error cannot be caught!* The error function (or similarly, the undefined value) should only be used when you know that it's not supposed to ever happen. (As a side note: the justExpose function is already available in the Data.Maybe module in the form of fromJust.)
[*] There are some tricks involving IO that can be used to catch it, but it can't be done in pure code without unsafePerformIO.

Shorter way to write this code

The following pattern appears very frequently in Haskell code. Is there a shorter way to write it?
if pred x
then Just x
else Nothing
You're looking for mfilter in Control.Monad:
mfilter :: MonadPlus m => (a -> Bool) -> m a -> m a
-- mfilter odd (Just 1) == Just 1
-- mfilter odd (Just 2) == Nothing
Note that if the condition doesn't depend on the content of the MonadPlus, you can write instead:
"foo" <$ guard (odd 3) -- Just "foo"
"foo" <$ guard (odd 4) -- Nothing
Hm... You are looking for a combinator that takes an a, a function a -> Bool and returns a Maybe a. Stop! Hoogle time. There is no complete match, but find is quite close:
find :: (a -> Bool) -> [a] -> Maybe a
I doubt that you can actually find your function somewhere. But why not define it by yourself?
ifMaybe :: (a -> Bool) -> a -> Maybe a
ifMaybe f a | f a = Just a
ifMaybe _ _ = Nothing
You can use guard to achieve this behavior:
guard (pred x) >> return x
This is such a generally useful behavior that I've even defined ensure in my own little suite of code for one-offs (everybody has such a thing, right? ;-):
ensure p x = guard (p x) >> return x
Use:
(?:) (5>2) (Just 5,Nothing)
from Data.Bool.HT.
f pred x = if pred x then Just x else Nothing
Given the above definition, you can simply write:
f pred x
Of course this is no different than Daniel Wagner's ensure or FUZxxl's ifMaybe. But it's name is simply f, making it the shortest, and it's definition is precisely the code you gave, making it the most easily proven correct. ;)
Some ghci, just for fun
ghci> let f pred x = if pred x then Just x else Nothing
ghci> f (5>) 2
Just 2
ghci> f (5>) 6
Nothing
If you couldn't tell, this isn't a very serious answer. The others are a bit more insightful, but I couldn't resist the tongue-in-cheek response to "make this code shorter".
Usually I'm a big fan of very generic code, but I actually find this exact function useful often enough, specialized to Maybe, that I keep it around instead of using guard, mfilter, and the like.
The name I use for it is justIf, and I'd typically use it for doing things like this:
∀x. x ⊢ import Data.List
∀x. x ⊢ unfoldr (justIf (not . null . snd) . splitAt 3) [1..11]
[[1,2,3],[4,5,6],[7,8,9]]
Basically, stuff where some sort of element-wise filtering or checking needs to be done in a compound expression, so Maybe is used to indicate the result of the predicate.
For the specialized version like this, there really isn't much you can do to make it shorter. It's already pretty simple. There's a fine line between being concise, and just golfing your code for character count, and for something this simple I wouldn't really worry about trying to "improve" it...

"maybe"-like function for Bool and List?

Sometimes i find myself progamming the pattern "if the Bool is not false" or "if the list is not empty use it, otherwise use something else".
I am looking for functions for Bool and List that are what the "maybe" function is to Maybe. Are there any?
Update: I meant to use the Bool-case as a generalization of the List-case. For example when working with Data.Text as T:
if T.null x then x else foo x
I am looking to reduce such boiler plate code.
maybe is the catamorphism of the Maybe type.
foldr is the catamorphism of the list type.
Data.Bool.bool is the catamorphism of the Bool type.
If you had used maybe like: maybe x (const y)
You could use: foldr (const (const y)) x
Your example if T.null x then x else foo x could be written with bool as
bool foo id (T.null x) x
(it takes the False case first, the opposite of if)
I think the answer is probably that there isn't such a generic function. As djv says, you can perhaps build on Data.Monoid to write one, something like:
maybe' :: (Eq a, Monoid a) => b -> (a -> b) -> a -> b
maybe' repl f x = if x == mempty then repl else f x
But I don't know of any functions in the standard library like that (or any that could easily be composed together to do so).
Check Data.Monoid, it's a typeclass describing data types which have a designated empty value and you can pattern-match on it to write your generic function. There are instances for Bool with empty value False and for List with empty value [].

Operating on a return from a Maybe that contains "Just"

I have a function that has a return type of Maybe ([(Int,Int)],(Int,Int))
I would like to call this from another function and perform an operation on the data.
However, the return value is contained within Just. The second method takes ([(Int,Int)],(Int,Int)) and therefore will not accept Just ([(Int,Int)],(Int,Int)).
Is there a way I can trim the Just before applying the second method?
I don't fully understand the use of Just within Maybe - however, I have been told that the return type for the first Method must be Maybe.
There are several solutions to your problem, all based around pattern matching. I'm assuming you have two algorithms (since you didn't name them, I will):
algorithm1 :: a -> Maybe b
algorithm2 :: b -> c
input :: a
1) Pattern matching is typically done from either a case statement (below) or a function.
let val = algorithm1 input
in case val of
Nothing -> defaultValue
Just x -> algorithm2 x
All other presented solutions use pattern matching, I'm just presenting standard functions that perform the pattern matching for you.
2) The prelude (and Data.Maybe) have some built-in functions to deal with Maybes. The maybe function is a great one, I suggest you use it. It's defined in standard libraries as:
maybe :: c -> (b -> c) -> Maybe b -> c
maybe n _ Nothing = n
maybe _ f (Just x) = f x
Your code would look like:
maybe defaultValue algorithm2 (algorithm1 input)
3) Since Maybe is a functor you could use fmap. This makes more sense if you don't have a default value. The definition:
instance Functor Maybe where
fmap _ Nothing = Nothing
fmap f (Just a) = Just (f a)
So your code would look like:
fmap algorithm2 (algorithm1 input)
This output will be a Maybe value (Nothing if the result of algorithm1 is Nothing).
4) Finally, and strongly discouraged, is fromJust. Only use it if you are positive the first algorithm will return Just x (and not Nothing). Be careful! If you call fromJust val when val = Nothing then you get an exception, which is not appreciated in Haskell. Its definition:
fromJust :: Maybe b -> b
fromJust Nothing = error "Maybe.fromJust: Nothing" -- yuck
fromJust (Just x) = x
Leaving your code to look like:
algorithm2 (fromJust (algorithm1 input))
You're looking for fromJust. But only if you're certain your Maybe function is not going to return a Nothing!

Applying a function that may fail to all values in a list

I want to apply a function f to a list of values, however function f might randomly fail (it is in effect making a call out to a service in the cloud).
I thought I'd want to use something like map, but I want to apply the function to all elements in the list and afterwards, I want to know which ones failed and which were successful.
Currently I am wrapping the response objects of the function f with an error pair which I could then effectively unzip afterwards
i.e. something like
g : (a->b) -> a -> [ b, errorBoolean]
f : a-> b
and then to run the code ... map g (xs)
Is there a better way to do this? The other alternative approach was to iterate over the values in the array and then return a pair of arrays, one which listed the successful values and one which listed the failures. To me, this seems to be something that ought to be fairly common. Alternatively I could return some special value. What's the best practice in dealing with this??
If f is making a call out to the cloud, than f is undoubtedly using some monad, probably the IO monad or a monad derived from the IO monad. There are monadic versions of map. Here is what you would typically do, as a first attempt:
f :: A -> IO B -- defined elsewhere
g :: [A] -> IO [B]
g xs = mapM f xs
-- or, in points-free style:
g = mapM f
This has the (possibly) undesirable property that g will fail, returning no values, if any call to f fails. We fix that by making it so f returns either an answer or an error message.
type Error = String
f :: A -> IO (Either Error B)
g :: [A] -> IO [Either Error B]
g = mapM f
If you want all of the errors to be returned together, and all of the successes clumped together, you can use the lefts and rights functions from Data.Either.
h :: [A] -> IO ([B], [Error])
h xs = do ys <- g xs
return (rights ys, lefts ys)
If you don't need the error messages, just use Maybe B instead of Either Error B.
The Either data type is the most common way to represent a value which can either result in an error or a correct value. Errors use the Left constructor, correct values use the Right constructor. As a bonus, "right" also means "correct" in English, but the reason that the correct value uses the Right constructor is actually deeper (because this means we can create a functor out of the Either type which modifies correct results, which is not possible over the Left constructor).
You could write your g to return a Maybe monad:
f: a -> b
g: (a -> b) -> a -> Maybe b
If f fails, g returns Nothing, otherwise it returns Just (f x).

Resources