Function in haskell that like catMaybes, but having type [Maybe a] -> Maybe [a] - haskell

I would like to have a function with the type:
f :: [Maybe a] -> Maybe [a]
e.g.
f [Just 3, Just 5] == Just [3, 5]
f [Just 3, Nothing] == Nothing
f [] == Just []
It is similar to catMaybes :: [Maybe a] -> [a] in Data.Maybe, except that catMaybes ignores Nothing, while my f is very serious about Nothing. I could implement f in a naive way (as shown below), but wondering if there is more idiomatic way (like "applicative functor"):
f :: [Maybe a] -> Maybe [a]
f xs = let ys = catMaybes xs
in if length ys == length xs
then Just ys
else Nothing
or
f :: [Maybe a] -> Maybe [a]
f xs = if all isJust xs
then catMaybes xs
else Nothing

The function you're searching for is called sequence:
sequence :: (Monad m) => [m a] -> m [a]
You can find this function using hoogle: link.
Example:
>>> sequence [Just 3, Just 5]
Just [3,5]
>>> sequence [] :: Maybe [Int]
Just []
Note: There is also sequenceA in Data.Traversable which is a bit generalized, but for your use case sequence from Control.Monad is enough.

You want sequence from Control.Monad.
(This is also generalized in a useful way in Data.Traversable.)

Related

Haskell: Create a list of tuples from a tuple with a static element and a list

Need to create a list of tuples from a tuple with a static element and a list. Such as:
(Int, [String]) -> [(Int, String)]
Feel like this should be a simple map call but am having trouble actually getting it to output a tuple as zip would need a list input, not a constant.
I think this is the most direct and easy to understand solution (you already seem to be acquainted with map anyway):
f :: (Int, [String]) -> [(Int, String)]
f (i, xs) = map (\x -> (i, x)) xs
(which also happens to be the desugared version of [(i, x) | x < xs], which Landei proposed)
then
Prelude> f (3, ["a", "b", "c"])
[(3,"a"),(3,"b"),(3,"c")]
This solution uses pattern matching to "unpack" the tuple argument, so that the first tuple element is i and the second element is xs. It then does a simple map over the elements of xs to convert each element x to the tuple (i, x), which I think is what you're after. Without pattern matching it would be slightly more verbose:
f pair = let i = fst pair -- get the FIRST element
xs = snd pair -- get the SECOND element
in map (\x -> (i, x)) xs
Furthermore:
The algorithm is no way specific to (Int, [String]), so you can safely generalize the function by replacing Int and String with type parameters a and b:
f :: (a, [b]) -> [(a, b)]
f (i, xs) = map (\x -> (i, x)) xs
this way you can do
Prelude> f (True, [1.2, 2.3, 3.4])
[(True,1.2),(True,2.3),(True,3.4)]
and of course if you simply get rid of the type annotation altogether, the type (a, [b]) -> [(a, b)] is exactly the type that Haskell infers (only with different names):
Prelude> let f (i, xs) = map (\x -> (i, x)) xs
Prelude> :t f
f :: (t, [t1]) -> [(t, t1)]
Bonus: you can also shorten \x -> (i, x) to just (i,) using the TupleSections language extension:
{-# LANGUAGE TupleSections #-}
f :: (a, [b]) -> [(a, b)]
f (i, xs) = map (i,) xs
Also, as Ørjan Johansen has pointed out, the function sequence does indeed generalize this even further, but the mechanisms thereof are a bit beyond the scope.
For completeness, consider also cycle,
f i = zip (cycle [i])
Using foldl,
f i = foldl (\a v -> (i,v) : a ) []
Using a recursive function that illustrates how to divide the problem,
f :: Int -> [a] -> [(Int,a)]
f _ [] = []
f i (x:xs) = (i,x) : f i xs
A list comprehension would be quite intuitive and readable:
f (i,xs) = [(i,x) | x <- xs]
Do you want the Int to always be the same, just feed zip with an infinite list. You can use repeat for that.
f i xs = zip (repeat i) xs

Flip Maybe and List

I want a function that takes in a list of Maybe a, and returns Just [a] if all contents are Just a, otherwise returns Nothing.
f :: [Maybe a] -> Maybe [a]
-- f [Just x, Just y ] = Just [x, y]
-- f [Just x, Nothing] = Nothing
I think it doesn't have to be Maybe and List but any Functor Applicative or Monad, but I can't think up the way.
This is a great example of where hoogle comes in handy. It's a search engine where you can enter a type signature and get the functions that match—even if they are more polymorphic.
Entering [Maybe a] -> Maybe [a] we get a bunch of results.
The first one is:
sequence :: Monad m => [m a] -> m [a]
We can try this out in GHCi:
Prelude> let xs = [Just 1, Just 2, Just 3]
Prelude> sequence xs
Just [1,2,3]
Prelude> let xs = [Just 1, Nothing, Just 3]
Prelude> sequence xs
Nothing
Hey, look at that: exactly what we were looking for! So the function you want is sequence which also happens to work for types other than Maybe.

Redefining monad list instance

I am attempting to redefine the monad list instance using newtype to create a wrapped list type, so as to allow this to be done at all, since it seems the Prelude definitions are unable to be overridden.
So far I have the following:
newtype MyList a = MyList { unMyList :: [a] }
deriving Show
myReturn :: a -> [a]
myReturn x = [x]
myBind :: [a] -> (a -> [b]) -> [b]
myBind m f = concat $ map f m
instance Monad MyList where
return x = MyList [x]
xs >>= f = undefined
As a beginner in Haskell, I am at a loss to know how to define the >>= operator for the instance, using my function for the definition of bind.
Should the myReturn and myBind functions have types using MyList rather than plain type variables? How does one do the packing and unpacking necessary to define >>= properly?
I am getting stuck on the function argument to map f, where f :: a -> [b], but it seems I need f :: a -> MyList b, but then map won't accept that as an argument.
Apologies for the confusion. All assistance appreciated.
[I am aware there is a similar question here: Redefine list monad instance but I'm afraid I cannot follow the answers there.]
You simply need to unwrap your MyList type, operate on it, then wrap it back up:
instance Monad MyList where
return x = MyList [x]
(MyList xs) >>= f = MyList . concat . map unMyList . map f $ xs
You can (and should) condense this to MyList $ concatMap (unMyList . f) xs, but I've left it expanded for illustrative purposes. You could simplify this definition by defining your own map and concat functions for MyList:
myMap :: (a -> b) -> MyList a -> MyList b
myMap f (MyList xs) = MyList $ map f xs
myConcat :: MyList (MyList a) -> MyList a
myConcat (MyList xs) = MyList $ concat $ map unMyList xs
myConcatMap :: (a -> MyList b) -> MyList a -> MyList b
myConcatMap f xs = myConcat $ myMap f xs
instance Monad MyList where
return x = MyList [x]
xs >>= f = myConcatMap f xs
And now it looks like the normal list instance:
instance Monad [] where
return x = [x]
xs >>= f = concatMap f xs

How to return a tuple array recursively in Haskell

I have the following function:
function :: [String] -> [[Int]] -> ([[Int]],[[Int]])
I would like to know if it is possible to do something like this:
function :: [String] -> [[Int]] -> ([[Int]],[[Int]])
function a (b:bs) = if condition then ([[]], [b]) ++ function a bs else
([b], [[]]) ++ function a bs
Of course I could write two functions which returns each [[Int]] but I would like to do it in a more appropriate way for Haskell.
There is a monoid instance for a tuple:
(Monoid a, Monoid b) => Monoid (a, b)
So the result of mappend will be:
([1], [2]) `mappend` ([3], [4])
([1, 3], [2, 4])
So basically you just replace ++ with mappend in your example
How about using map?
import Data.Monoid
f :: t -> [a] -> ([a], [a])
f a = mconcat . map part
where part b = if True then ([], [b]) else ([b], [])
So we let part choose which list our element of b will go in and let `map, and mconcat to flatten it.
It's idiomatic haskell to avoid explicit recursion so while you can fix your code by substituting mappend for ++ since you asked for the more appropriate haskell way I'll suggest this.
Oh also, you could just use break
f s = break $ \b -> condition
The most Haskellic(?) way would probably be to use unzip:
function a bs = unzip $ function' a bs
where function' a (b:bs) = (if condition then ([], b) else (b, [])) : function' a bs
function' _ [] = [] -- You forgot the base case.

Best practice how to evaluate a list of Maybes

i am looking for a function which takes a function (a -> a -> a) and a list of [Maybe a] and returns Maybe a. Hoogle gave me nothing useful. This looks like a pretty common pattern, so i am asking if there is a best practice for this case?
>>> f (+) [Just 3, Just 3]
Just 6
>>> f (+) [Just 3, Just 3, Nothing]
Nothing
Thanks in advance, Chris
You should first turn the [Maybe a] into a Maybe [a] with all the Just elements (yielding Nothing if any of them are Nothing).
This can be done using sequence, using Maybe's Monad instance:
GHCi> sequence [Just 1, Just 2]
Just [1,2]
GHCi> sequence [Just 1, Just 2, Nothing]
Nothing
The definition of sequence is equivalent to the following:
sequence [] = return []
sequence (m:ms) = do
x <- m
xs <- sequence ms
return (x:xs)
So we can expand the latter example as:
do x <- Just 1
xs <- do
y <- Just 2
ys <- do
z <- Nothing
zs <- return []
return (z:zs)
return (y:ys)
return (x:xs)
Using the do-notation expression of the monad laws, we can rewrite this as follows:
do x <- Just 1
y <- Just 2
z <- Nothing
return [x, y, z]
If you know how the Maybe monad works, you should now understand how sequence works to achieve the desired behaviour. :)
You can then compose this with foldr using (<$>) (from Control.Applicative; equivalently, fmap or liftM) to fold your binary function over the list:
GHCi> foldl' (+) 0 <$> sequence [Just 1, Just 2]
Just 3
Of course, you can use any fold you want, such as foldr, foldl1 etc.
As an extra, if you want the result to be Nothing when the list is empty, and thus be able to omit the zero value of the fold without worrying about errors on empty lists, then you can use this fold function:
mfoldl1' :: (MonadPlus m) => (a -> a -> a) -> [a] -> m a
mfoldl1' _ [] = mzero
mfoldl1' f (x:xs) = return $ foldl' f x xs
and similarly for foldr, foldl, etc. You'll need to import Control.Monad for this.
However, this has to be used slightly differently:
GHCi> mfoldl1' (+) =<< sequence [Just 1, Just 2]
Just 3
or
GHCi> sequence [Just 1, Just 2] >>= mfoldl1' (+)
Just 3
This is because, unlike the other folds, the result type looks like m a instead of a; it's a bind rather than a map.
As I understand it, you want to get the sum of a bunch of maybes or Nothing if any of them are Nothing. This is actually pretty simple:
maybeSum = foldl1 (liftM2 (+))
You can generalize this to something like:
f :: Monad m => (a -> a -> a) -> [m a] -> m a
f = foldl1 . liftM2
When used with the Maybe monad, f works exactly the way you want.
If you care about empty lists, you can use this version:
f :: MonadPlus m => (a -> a -> a) -> [m a] -> m a
f _ [] = mzero
f fn (x:xs) = foldl (liftM2 fn) x xs
What about something as simple as:
λ Prelude > fmap sum . sequence $ [Just 1, Just 2]
Just 3
λ Prelude > fmap sum . sequence $ [Just 1, Just 2, Nothing]
Nothing
Or, by using (+):
λ Prelude > fmap (foldr (+) 0) . sequence $ [Just 1, Just 2]
Just 3
λ Prelude > fmap (foldr (+) 0) . sequence $ [Just 1, Just 2, Nothing]
Nothing
So, maybeSum = fmap sum . sequence.

Resources