I need a monad solution to a functor simplification - haskell

This extends from a solution I have used for my this question
data CoroMap a = CoroMap (ColorMap (RoleMap a))
instance Functor CoroMap where
fmap fn (CoroMap coro) =
CoroMap $ fmap (fmap fn) coro
visions:: Piese -> [Vision]
visions p = []
ihavethis :: CoroMap [Piese]
ineedthis:: CoroMap [Vision]
-- ineedthis = ???
-- I have this a -> [b]
-- I need this [a] -> [b]
-- specifically converting CoroMap [Piese] to CoroMap [Vision]
-- using Piese -> [Vision]

I have this a -> [b]
I need this [a] -> [b]
A lot of questions like this in Haskell basically boil down to "following the types" - meaning that (sometimes, although not always) you don't have to think too hard about what you actually want the function to do, you just need the types to match up. (This might seem rather miraculous, and in a way it is - it's due to the fact that types in Haskell give you so much information compared to many other statically-typed languages.) And the ability to pick a function which has the right type often simply comes with a bit of experience.
Even if you don't have much experience, there is a very good way to "cheat" - go to Hoogle and type in the type signature you are interested in. Here, entering
(a -> [b]) -> [a] -> [b]
and letting it search will bring up a lot of relevant results, of which the very first is concatMap. This is the function that, given such a function of type a -> [b] and a list of type [a], first maps the function over the list, resulting in a list of lists ([[b]]), then concatenates those together to get a simple [b]. That's very likely what you want (and seems to be the case, based on your response to my comment suggesting it).
In terms of being able to spot this without needing a helper like Hoogle - Monads are ubiquitous in Haskell, and lists are one of many very common type which form a monad. Seeing therefore that you have a a -> m b (for a particular monad m) and want a m a -> m b, any Haskeller with a little bit of experience will instantly think of the fundamental method of the Monad typeclass, which is (>>=) (pronounced "bind"), and has type
(Monad m) => m a -> (a -> m b) -> m b
This is very close to what you want, the only difference is that you have to flip it, to get:
flip (>>=) :: (Monad m) => (a -> m b) -> m a -> m b
which due to currying (aka "arrows in type signatures are right-associative"), is the same as
flip (>>=) :: (Monad m) => (a -> m b) -> (m a -> m b)
which is exactly what you asked for, only it will work for all Monads, not just lists. That's how I came up with concatMap, because (>>=) for lists is defined to be flip concatMap, so the flip (>>=) that you want is simply concatMap.
Note also that the Hoogle search I mentioned above lists (=<<) a short way down - that's just an abbreviation for flip (>>=). So this all marries up nicely.
Finally, for your bonus question:
I need this function f [a] -> (a -> [b]) -> f [b]
where from context f is a Functor - this is just a case of combining what we already have:
concatMap :: (a -> [b]) -> ([a] -> [b])`
with fmap. Given g :: a -> [b] we know concatMap g is of type [a] -> [b], so fmap (concatMap g) is of type f [a] -> f [b]. In other words, \g -> fmap (concatMap g) (which you can also write as fmap . concatMap) has type (a -> [b]) -> f [a] -> f [b], so we simply need to apply swap the arguments. So the function you want is
flip (fmap . concatMap)
in pointfree form, or if you prefer explicit arguments (which looks less elegant but is often easier to understand), you can write it as
\as g -> fmap (concatMap g) as

Related

Having a custom fmap traversing until non Functor type is found

In my learning curve of Haskell, I am wondering if it possible to implement a custom fmap function, fmap' , that would "apply" until a non Functor is found.
For example; with fmap , one has to write
fmap (fmap (*2)) [[1,2] , [ 3,4 ,5]]
[[2,4],[6,8,10]]
or
fmap (fmap (*2)) [Just 1, Just 2]
[Just 2,Just 4]
The idea is to write
fmap' (*2) [[1,2] , [3,4,5]]
fmap' (*2) [Just 1 , Just 2]
to get the same result as above.
My current understanding is that it is not possible because fmap' and fmap do not have the same signature as
:t fmap (fmap)
fmap (fmap)
:: (Functor f2, Functor f1) => f1 (a -> b) -> f1 (f2 a -> f2 b)
You are looking for a function:
rfmap :: (a -> b) -> F a -> F b
where F is some arbitrary "context" of a, which may be quite sophisticated. E.g. one specialization would be:
rfmap :: (a -> b) -> Maybe (Int -> Either Bool a) -> Maybe (Int -> Either Bool b)
We need the typechecker to figure out that F = Maybe (Int -> Either Bool _). This is not as easy as fmap, whose argument is a type constructor applied to a variable
fmap :: (a -> b) -> Compose Maybe (Either Bool) a -> Compose Maybe (Either Bool) b
^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^
and is easily found, because type constructors are injective.
rfmap needs to deal with some tricky ambiguities. Consider:
rfmap id (Just [42])
Which specialization should we choose?
rfmap :: (Int -> Int) -> Maybe [Int] -> Maybe [Int]
rfmap :: ([Int] -> [Int]) -> Maybe [Int] -> Maybe [Int]
rfmap :: (Maybe [Int] -> Maybe [Int]) -> Maybe [Int] -> Maybe [Int]
That is, do we consider the functor Maybe _ or Maybe (Int -> _), or even the identity functor _? You probably want to say "as deep as possible", but alas, that interferes with polymorphism:
f :: a -> Maybe a
f x = rfmap id (Just x)
You probably want this to just be one fmap, because going deeper doesn't typecheck. However if we pass f [42] then it's the same as the expression above which goes down two by the "as deep as possible" rule -- so this is something like like a violation of referential transparency (I wouldn't consider it a full violation because there is hidden type-directed information that might differ).
Nevermind that there might be a Num instance for a functor, e.g. Num a => Num (Vector a), which would mean that [42] is actually more than two levels deep.
So there are a lot of hard questions that make something like rfmap unlikely to have a well-behaved implementation.
As usual, if you give up polymorphism (which is a terrible idea), you can hack something together with typeclasses. It also has some other problems.
I would recommend against expecting any solution to be usable. It's the kind of thing that's not very compatible with Haskell's type system.
As far as alternatives:
If you are writing a single instance and just annoyed with all the fmaps, look at semantic editor combinators for a nice way to think about it.
If you are making abstractions (in the sense of a type w/ operations) which are just nested functors and annoyed by the tedious reimplementation of fmap = fmap.fmap.fmap, then using Compose is the way to go.

Partially applying <*> with zip

I started to look at some Haskell code and found:
foo :: ([a] -> [b]) -> [a] -> [(a, b)]
let foo = (<*>) zip
I don't understand how this works, ap expects a f (a -> b) -> f a but zip is of type [a] -> [b] -> ([a, b]). I understand that f a -> f b would match [a] -> [b], but not f (a -> b).
Let's work out the types by hand. First, what are the types of the relevant expressions?
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
zip :: [a] -> [b] -> [(a, b)]
Now, we need to unify the type of zip with the type of the first argument to (<*>). Let's rename the unrelated as and bs:
Applicative f => f (a -> b)
[c] -> [d] -> [(c, d)]
First, what is f? What Applicative are we working in? The type of the bottom half is a function, so f must be ((->) [c]), or "functions taking a list of c as input". And once we've done that, we can see that:
f ~ ((->) [c])
a ~ [d]
b ~ [(c, d)]
Now that we've got the types to match up, we can look up the definition of (<*>) for functions:
instance Applicative ((->) a) where
pure = const
(<*>) f g x = f x (g x)
Substituting zip for f here, and rewriting as a lambda, yields:
(<*>) zip = \g x -> zip x (g x)
So, this needs a function from [a] -> [b] and an [a], and zips the input list with the result of calling the function on it.
That makes sense mechanically, but why? What more general understanding can lead us to this conclusion without having to work everything out by hand? I'm not sure my own explanation of this will be useful, so you may want to study the instances for ((->) t) yourself if you don't understand what's going on. But in case it is useful, here is a handwavy expanation.
The Functor, Applicative, and Monad instances for ((->) t) are the same as Reader t: "functions which have implicit access to a value of type t". (<*>) is about calling a function inside of an Applicative wrapper, which for functions is a two-argument function. It arranges that the "implicit" argument be passed to f, yielding another function, and calls that function with the value obtained by passing the implicit argument to g as well. So, (<*>) f, for some f, is "Give me another function, and a value x, and I'll pass x to both f and the other function".

Understanding `mapA` to Gain Intuition

I'm working on an exercise from Brent Yorgey's 2013 UPenn lecture to implement mapA.
mapA :: Applicative f => (a -> f b) -> ([a] -> f [b])
I'm trying to gain intuition for this function. How is this function useful? I'm not questioning its utility - just trying to understand it.
Additionally, I'm looking for a hint to go from a -> f b to [a] -> f [b].
If we knew nothing at all about f then a function like a -> f b would let us put things into f-boxes but then we'd be completely stuck. You're probably familiar with Functor. If we know f were a Functor then we'd be able to transform the thing inside of f, but we're still basically stuck---f forms an unmoving wall we cannot cross.
Why do we care? Well, when we try to construct the function [a] -> f [b] we need to some how operate on a collection of as. We could, perhaps, just pull the first one off if we liked (and it existed) and feed it through a -> f b then wrap the result in a list:
unsatisfying :: Functor f => (a -> f b) -> ([a] -> f [b])
unsatisfying inject (a : _) = fmap (\x -> [x]) (inject a)
but not only do we have an incomplete pattern match on [a], we're clearly violating something in the spirit of this function---we'd much prefer to use all of the as. Unfortunately, knowing only f or even that f is a Functor gets us only as far as
stillUnsatisfying :: Functor f => (a -> f b) -> ([a] -> [f b])
stillUnsatisfying inject as = map inject as
The problem is that just because we have a collection of f-containers doesn't mean we can find any way to treat them collectively. We'd like to somehow "glue" our collection [f b] all together. If we could do that then a function like [a] -> f [b] would sound like "explode our list [a] into pieces, pass them each individually into f using inject, glom all of the (f b)s together, and then reassemble the list on the inside".
Clearly we need a way to "glom" Functors together and also a way to operate on the separate pieces "on the inside" of f.
So this is where Applicative comes in. I'm not going to introduce it exactly, though. Instead, let's look at an equivalent type class
class Functor f => Monoidal f where
basic :: a -> f a
glom :: f a -> f b -> f (a, b)
It's an interesting exercise to prove that Monoidal and Applicative are equivalent, but immediately you can see that glom provides exactly what we're looking for. Moreover, basic/pure give us the ability to inject raw pieces of our list into f as we need them (for instance, if our [a] is empty then we'll need to inject an empty list into f without using a -> f b as we cannot---that looks like basic [] :: f [b]).
So Applicative provides you the ability to not only transform inside of functors but also to glom a bunch of functors together and operate on all of their pieces inside of the functor.
You're halfway there, but the final function you're looking for is the sequenceA function that's defined in LYAH. Here's my implementation:
sequenceA :: Applicative f => [f a] -> f [a]
sequenceA = foldr ((<*>) . fmap (:)) (pure [])
From there the mapA function is easy as pie. Just add another argument and compose the two functions:
mapA :: Applicative f => (a -> f b) -> [a] -> f [b]
mapA f xs = foldr ((<*>) . fmap (:) . f) (pure []) xs
-- Or, you could implement it this more elegant, albeit slightly slower, way:
mapA = (sequenceA .) . map
And there you have an implementation for you to have a look at. As for the usefulness, it's particularly useful in IO, when you have a list like ["Foo","Bar","Baz"], and you'd like to putStrLn all of those functions. Do do so, you will need to map each value and the sequence it, which mapA does. Note that these functions have monadic equivalents, but it's a good exercise to implement them in purely Applicative ways.
These functions are both quite useful when dealing with lists of Applicatives, allowing one to more easily manipulate the values inside them without using half a ton of fmaps.
We already know that map :: (a -> b) -> ([a] -> [b]) is useful. It applies a function to every element of a list.
A loose but enlightening interpretation of a -> f b for an applicative f is that it is a function which takes an a, performs an applicative "action", and returns a b. For example if f is IO then the "action" might be reading from a disk. mapA :: (a -> f b) -> ([a] -> f [b]) can be interpreted as applying this "function" to every element of the list.

Why use such a peculiar function type in monads?

New to Haskell, and am trying to figure out this Monad thing. The monadic bind operator -- >>= -- has a very peculiar type signature:
(>>=) :: Monad m => m a -> (a -> m b) -> m b
To simplify, let's substitute Maybe for m:
(>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b
However, note that the definition could have been written in three different ways:
(>>=) :: Maybe a -> (Maybe a -> Maybe b) -> Maybe b
(>>=) :: Maybe a -> ( a -> Maybe b) -> Maybe b
(>>=) :: Maybe a -> ( a -> b) -> Maybe b
Of the three the one in the centre is the most asymmetric. However, I understand that the first one is kinda meaningless if we want to avoid (what LYAH calls boilerplate code). However, of the next two, I would prefer the last one. For Maybe, this would look like:
When this is defined as:
(>>=) :: Maybe a -> (a -> b) -> Maybe b
instance Monad Maybe where
Nothing >>= f = Nothing
(Just x) >>= f = return $ f x
Here, a -> b is an ordinary function. Also, I don't immediately see anything unsafe, because Nothing catches the exception before the function application, so the a -> b function will not be called unless a Just a is obtained.
So maybe there is something that isn't apparent to me which has caused the (>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b definition to be preferred over the much simpler (>>=) :: Maybe a -> (a -> b) -> Maybe b definition? Is there some inherent problem associated with the (what I think is a) simpler definition?
It's much more symmetric if you think in terms the following derived function (from Control.Monad):
(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> (a -> m c)
(f >=> g) x = f x >>= g
The reason this function is significant is that it obeys three useful equations:
-- Associativity
(f >=> g) >=> h = f >=> (g >=> h)
-- Left identity
return >=> f = f
-- Right identity
f >=> return = f
These are category laws and if you translate them to use (>>=) instead of (>=>), you get the three monad laws:
(m >>= g) >>= h = m >>= \x -> (g x >>= h)
return x >>= f = f x
m >>= return = m
So it's really not (>>=) that is the elegant operator but rather (>=>) is the symmetric operator you are looking for. However, the reason we usually think in terms of (>>=) is because that is what do notation desugars to.
Let us consider one of the common uses of the Maybe monad: handling errors. Say I wanted to divide two numbers safely. I could write this function:
safeDiv :: Int -> Int -> Maybe Int
safeDiv _ 0 = Nothing
safeDiv n d = n `div` d
Then with the standard Maybe monad, I could do something like this:
foo :: Int -> Int -> Maybe Int
foo a b = do
c <- safeDiv 1000 b
d <- safeDiv a c -- These last two lines could be combined.
return d -- I am not doing so for clarity.
Note that at each step, safeDiv can fail, but at both steps, safeDiv takes Ints, not Maybe Ints. If >>= had this signature:
(>>=) :: Maybe a -> (a -> b) -> Maybe b
You could compose functions together, then give it either a Nothing or a Just, and either it would unwrap the Just, go through the whole pipeline, and re-wrap it in Just, or it would just pass the Nothing through essentially untouched. That might be useful, but it's not a monad. For it to be of any use, we have to be able to fail in the middle, and that's what this signature gives us:
(>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b
By the way, something with the signature you devised does exist:
flip fmap :: Maybe a -> (a -> b) -> Maybe b
The more complicated function with a -> Maybe b is the more generic and more useful one and can be used to implement the simple one. That doesn't work the other way around.
You can build a a -> Maybe b function from a function f :: a -> b:
f' :: a -> Maybe b
f' x = Just (f x)
Or, in terms of return (which is Just for Maybe):
f' = return . f
The other way around is not necessarily possible. If you have a function g :: a -> Maybe b and want to use it with the "simple" bind, you would have to convert it into a function a -> b first. But this doesn't usually work, because g might return Nothing where the a -> b function needs to return a b value.
So generally the "simple" bind can be implemented in terms of the "complicated" one, but not the other way around. Additionally, the complicated bind is often useful and not having it would make many things impossible. So by using the more generic bind monads are applicable to more situations.
The problem with the alternative type signature for (>>=) is that it only accidently works for the Maybe monad, if you try it out with another monad (i.e. List monad) you'll see it breaks down at the type of b for the general case. The signature you provided doesn't describe a monadic bind and the monad laws can't don't hold with that definition.
import Prelude hiding (Monad, return)
-- assume monad was defined like this
class Monad m where
(>>=) :: m a -> (a -> b) -> m b
return :: a -> m a
instance Monad Maybe where
Nothing >>= f = Nothing
(Just x) >>= f = return $ f x
instance Monad [] where
m >>= f = concat (map f m)
return x = [x]
Fails with the type error:
Couldn't match type `b' with `[b]'
`b' is a rigid type variable bound by
the type signature for >>= :: [a] -> (a -> b) -> [b]
at monadfail.hs:12:3
Expected type: a -> [b]
Actual type: a -> b
In the first argument of `map', namely `f'
In the first argument of `concat', namely `(map f m)'
In the expression: concat (map f m)
The thing that makes a monad a monad is how 'join' works. Recall that join has the type:
join :: m (m a) -> m a
What 'join' does is "interpret" a monad action that returns a monad action in terms of a monad action. So, you can think of it peeling away a layer of the monad (or better yet, pulling the stuff in the inner layer out into the outer layer). This means that the 'm''s form a "stack", in the sense of a "call stack". Each 'm' represents a context, and 'join' lets us join contexts together, in order.
So, what does this have to do with bind? Recall:
(>>=) :: m a -> (a -> m b) -> m b
And now consider that for f :: a -> m b, and ma :: m a:
fmap f ma :: m (m b)
That is, the result of applying f directly to the a in ma is an (m (m b)). We can apply join to this, to get an m b. In short,
ma >>= f = join (fmap f ma)

Does a function like this already exist? (Or, what's a better name for this function?)

I've written code with the following pattern several times recently, and was wondering if there was a shorter way to write it.
foo :: IO String
foo = do
x <- getLine
putStrLn x >> return x
To make things a little cleaner, I wrote this function (though I'm not sure it's an appropriate name):
constM :: (Monad m) => (a -> m b) -> a -> m a
constM f a = f a >> return a
I can then make foo like this:
foo = getLine >>= constM putStrLn
Does a function/idiom like this already exist? And if not, what's a better name for my constM?
Well, let's consider the ways that something like this could be simplified. A non-monadic version would I guess look something like const' f a = const a (f a), which is clearly equivalent to flip const with a more specific type. With the monadic version, however, the result of f a can do arbitrary things to the non-parametric structure of the functor (i.e., what are often called "side effects"), including things that depend on the value of a. What this tells us is that, despite pretending like we're discarding the result of f a, we're actually doing nothing of the sort. Returning a unchanged as the parametric part of the functor is far less essential, and we could replace return with something else and still have a conceptually similar function.
So the first thing we can conclude is that it can be seen as a special case of a function like the following:
doBoth :: (Monad m) => (a -> m b) -> (a -> m c) -> a -> m c
doBoth f g a = f a >> g a
From here, there are two different ways to look for an underlying structure of some sort.
One perspective is to recognize the pattern of splitting a single argument among multiple functions, then recombining the results. This is the concept embodied by the Applicative/Monad instances for functions, like so:
doBoth :: (Monad m) => (a -> m b) -> (a -> m c) -> a -> m c
doBoth f g = (>>) <$> f <*> g
...or, if you prefer:
doBoth :: (Monad m) => (a -> m b) -> (a -> m c) -> a -> m c
doBoth = liftA2 (>>)
Of course, liftA2 is equivalent to liftM2 so you might wonder if lifting an operation on monads into another monad has something to do with monad transformers; in general the relationship there is awkward, but in this case it works easily, giving something like this:
doBoth :: (Monad m) => ReaderT a m b -> ReaderT a m c -> ReaderT a m c
doBoth = (>>)
...modulo appropriate wrapping and such, of course. To specialize back to your original version, the original use of return now needs to be something with type ReaderT a m a, which shouldn't be too hard to recognize as the ask function for reader monads.
The other perspective is to recognize that functions with types like (Monad m) => a -> m b can be composed directly, much like pure functions. The function (<=<) :: Monad m => (b -> m c) -> (a -> m b) -> (a -> m c) gives a direct equivalent to function composition (.) :: (b -> c) -> (a -> b) -> (a -> c), or you can instead make use of Control.Category and the newtype wrapper Kleisli to work with the same thing in a generic way.
We still need to split the argument, however, so what we really need here is a "branching" composition, which Category alone doesn't have; by using Control.Arrow as well we get (&&&), letting us rewrite the function as follows:
doBoth :: (Monad m) => Kleisli m a b -> Kleisli m a c -> Kleisli m a (b, c)
doBoth f g = f &&& g
Since we don't care about the result of the first Kleisli arrow, only its side effects, we can discard that half of the tuple in the obvious way:
doBoth :: (Monad m) => Kleisli m a b -> Kleisli m a c -> Kleisli m a c
doBoth f g = f &&& g >>> arr snd
Which gets us back to the generic form. Specializing to your original, the return now becomes simply id:
constKleisli :: (Monad m) => Kleisli m a b -> Kleisli m a a
constKleisli f = f &&& id >>> arr snd
Since regular functions are also Arrows, the definition above works there as well if you generalize the type signature. However, it may be enlightening to expand the definition that results for pure functions and simplify as follows:
\f x -> (f &&& id >>> arr snd) x
\f x -> (snd . (\y -> (f y, id y))) x
\f x -> (\y -> snd (f y, y)) x
\f x -> (\y -> y) x
\f x -> x.
So we're back to flip const, as expected!
In short, your function is some variation on either (>>) or flip const, but in a way that relies on the differences--the former using both a ReaderT environment and the (>>) of the underlying monad, the latter using the implicit side-effects of the specific Arrow and the expectation that Arrow side effects happen in a particular order. Because of these details, there's not likely to be any generalization or simplification available. In some sense, the definition you're using is exactly as simple as it needs to be, which is why the alternate definitions I gave are longer and/or involve some amount of wrapping and unwrapping.
A function like this would be a natural addition to a "monad utility library" of some sort. While Control.Monad provides some combinators along those lines, it's far from exhaustive, and I could neither find nor recall any variation on this function in the standard libraries. I would not be at all surprised to find it in one or more utility libraries on hackage, however.
Having mostly dispensed with the question of existence, I can't really offer much guidance on naming beyond what you can take from the discussion above about related concepts.
As a final aside, note also that your function has no control flow choices based on the result of a monadic expression, since executing the expressions no matter what is the main goal. Having a computational structure independent of the parametric content (i.e., the stuff of type a in Monad m => m a) is usually a sign that you don't actually need a full Monad, and could get by with the more general notion of Applicative.
Hmm, I don't think constM is appropriate here.
map :: (a -> b) -> [a] -> [b]
mapM :: (Monad m) => (a -> m b) -> [a] -> m b
const :: b -> a -> b
So perhaps:
constM :: (Monad m) => b -> m a -> m b
constM b m = m >> return b
The function you are M-ing seems to be:
f :: (a -> b) -> a -> a
Which has no choice but to ignore its first argument. So this function does not have much to say purely.
I see it as a way to, hmm, observe a value with a side effect. observe, effect, sideEffect may be decent names. observe is my favorite, but maybe just because it is catchy, not because it is clear.
I don't really have a clue this exactly allready exists, but you see this a lot in parser-generators only with different names (for example to get the thing inside brackets) - there it's normaly some kind of operator (>>. and .>> in fparsec for example) for this. To really give a name I would maybe call it ignore?
There's interact:
http://hackage.haskell.org/packages/archive/haskell98/latest/doc/html/Prelude.html#v:interact
It's not quite what you're asking for, but it's similar.

Resources