Flip Maybe and List - haskell

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.

Related

Difference between >>= and concatMap

I was playing around with >>= today, trying to understand monads, and found an interesting pattern. When working with the list monad, >>= seemed to behave like concatMap. I searched around to try to find any similarity, looking specifically in the definitions on hackage.
Some things I tried:
[1, 2, 3] >>= (iter 5 id) => [1,1,1,1,1,2,2,2,2,2,3,3,3,3,3]
concatMap (iter 5 id) [1, 2, 3]=> [1,1,1,1,1,2,2,2,2,2,3,3,3,3,3]
[1, 2, 3] >>= (iter 5 (+5)) => [1,6,11,16,21,2,7,12,17,22,3,8,13,18,23]
concatMap (iter 5 (+5) ) [1, 2, 3] => [1,6,11,16,21,2,7,12,17,22,3,8,13,18,23]
iter is just non-infinite iterate,
iter i f a = toL $ Data.Sequence.iterateN i f a
where
toL = Data.Foldable.toList :: Data.Sequence.Seq a -> [a]
(working in repl.it so the imports are screwed up).
Is (>>=) equivalent to concatMap for lists?
Is it the generalization of concatMap?
Yes, with the arguments flipped. Comparing these type signatures should bring out the similarity, though the special list syntax interferes:
Prelude> :t flip concatMap
flip concatMap :: Foldable t => t a -> (a -> [b]) -> [b]
Prelude> :t (>>=)
(>>=) :: Monad m => m a -> (a -> m b) -> m b
Yes, (=<<) is concatMap for lists. >>= is just a combination of fmap and join (the generalization of concat) for any Monad, so this makes intuitive sense as well.

Understand and use the basic concept of Haskell's Integral typeclass

I'm taking a course which focuses on Haskell & Prolog and there's an upcoming test for which i'm studying.
We're given a signature:
myList
:: (Integral a)
=> [a]
And we have to create a variable myList which will return an infinite list which is different from standard positive integer list by changing the position of every third element by moving it two positions to the right, starting from the first one.
So for example, the beginning would look like:
2,3,1,5,6,4,8,9,7.. on a standard list which contains positive elements.
I tried to solve this with a code like this:
myList (x:y:z:xs)
= y:z:x:(myList(xs))
myList [] = []
myList [x] = [x]
It gives the result needed but it's not following the signature. Could someone explain how to solve it so it would fit the signature and why it does.
Thanks.
The function (the implementation of which you got perfectly right, as a matter of fact)
myList (x:y:z:xs) = y:z:x:(myList xs)
myList [] = []
myList [x] = [x]
is generic enough not to depend on the type of the elements in the list to be Integral a => a. So if you let Haskell infer its type, it will infer [a] -> [a]. If you constraint the type to Integral a => [a] -> [a], it will still work, but be less generic, which will limit uses to just integral types.
Here's a demonstration of the principle:
Prelude> :{
Prelude| let myList (x:y:z:xs) = y:z:x:(myList(xs))
Prelude| myList [] = []
Prelude| myList [x] = [x]
Prelude| :}
Prelude> :t myList
myList :: [a] -> [a]
Prelude> take 15 $ myList ['a'..]
"bcaefdhigkljnom"
Prelude> take 15 $ myList [1..]
[2,3,1,5,6,4,8,9,7,11,12,10,14,15,13]
but
Prelude> :{
Prelude| let myList :: Integral a => [a] -> [a]
Prelude| myList (x:y:z:xs) = y:z:x:(myList(xs))
Prelude| myList [] = []
Prelude| myList [x] = [x]
Prelude| :}
Prelude> :t myList
myList :: Integral a => [a] -> [a]
Prelude> take 15 $ myList [1..]
[2,3,1,5,6,4,8,9,7,11,12,10,14,15,13]
Prelude> take 15 $ myList ['a'..]
<interactive>:34:11:
No instance for (Integral Char) arising from a use of ‘myList’
In the second argument of ‘($)’, namely ‘myList ['a' .. ]’
In the expression: take 15 $ myList ['a' .. ]
In an equation for ‘it’: it = take 15 $ myList ['a' .. ]
So the point is, both definitions are equivalent and capable of doing the same thing just as well as the other, but the constrained type signature is (and I'd say unjustifiably) less useful than the one with the general type signature.
If the assignment demands a function of type Integral a => [a] -> [a], all you really need to do is simply annotate the function you already have with exactly that type signature. There is, however, no (reasonable/rational) way to somehow guide Haskell to infer that type from the function definition, as that would necessitate somehow indirectly indicating that the list must contain values of a type that support the operations in Integral ... yada yada.
As a final note: you got the implementation/algorithm perfectly right, but fell short on type signatures and the notion of generality.
EDIT: if what you actually need is not a function but a list (your question is a bit ambiguous in this respect), all you need to do is rename the below definition of myList to e.g. myList' or go (which I think is quite a typical name for nested recursive helpers) or something (which can but doesn't have to be an hidden within the list myList) and then pass [1..] to it, assigning the result to myList:
myList :: Integral a => [a]
myList = go [1..]
where go (x:y:z:xs) = y:z:x:(go xs)
go [] = []
go [x] = [x]
of course looked this way, Integral a => [a] is indeed quite general a signature for the list (but not the most general, which would be (Enum a, Num a) => [a] as I was led to realize by dfeuer's comment), because the type a cannot be determined by the type of the input passed to the function, because you're always passing [1..].
If we want to give an answer with the right signature without supplying any signatures by hand, we have to look at the Integral class and look which methods it implements. Applying any such method is likely to force the right signature.
Prelude> :i Integral
class (Real a, Enum a) => Integral a where
quot :: a -> a -> a
rem :: a -> a -> a
div :: a -> a -> a
mod :: a -> a -> a
quotRem :: a -> a -> (a, a)
divMod :: a -> a -> (a, a)
toInteger :: a -> Integer
Since our sequence has something to do with remainders of division by 3, div and mod look promising.
After some fiddling with arithmetic, we arrive at something like
Prelude> let myList = map (\x -> x - x `mod` 3 + (x+2) `mod` 3 + 1) [0..]
Prelude> :t myList
myList :: Integral b => [b]

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.

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

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.)

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