:1:0:

Precedence parsing error

cannot mix `>>=' [infixl 1] and `>>>' [infixr 1] in the same infix expression

-----

now here is all that is needed to fix that problem as the improper mixing is between the monad bind { >>= } and the arrow { >>> } operators. The applicative { <$> } is already enclosed or it would ring bells with both the >>= and the >>>. So here is the fix:



-------

*Big3> [[2,4,6],[7..13],[10,20..100]] >>= (((* 3) <$>) >>> return)

[[6,12,18],[21,24,27,30,33,36,39],[30,60,9 0,120,150,180,210,240,270,300]]

-------

NOTICE that this is the same as the { return . fmap (* 3) } above.. just using all three notations.. I never said that it will always be a less obsfucated choice.. but sometimes it is a much better choice. The real point is that you do have the choice. Now that should serve to show everything a person would need to see that they can be mixed.. but more is at hand. This is and applicative functor operation " (^ 2) <$> " being applied to a list value generated by an enclosed monad, " ([1..10] >>= return . (* 5)) ".

----

*Big3> (^ 2) <$> ([1..10] >>= return . (* 5))

[25,100,225,400,625,900,1225,1600,2025,2 500]

-----

Now a better way in my opinion to skin that cat is to skip the monadic element and use an arrow computational element composed of the (* 5) and the (^ 2) directly applied to the initial list [1..10].

------

*Big3> ((* 5) >>> (^ 2)) <$> [1..10]

[25,100,225,400,625,900,1225,1600,2025,2 500]

------

This keeps all the computational elements grouped together and is more easily read, and due to the use of the >>> the computations are written in a more natural to me anyway left to right progress of the various functions being applied. If you are really enamored by the right to left of the (.) , composition notations, well you can always use a series of the arrow operators (<<<) that accomplish that.

Okay here is the true motivation to using arrows ... as the notation for splitting into two branches and doing separate computations on both sides is not as clean in much of any other type of notation. In this case a list of the pairs consisting of the "id" of the element being operated on from the original list, and the result of the computation.

-------

*Big3> (id &&& ((* 5) >>> (^ 2))) <$> [1..5]

[(1,25),(2,100),(3,225),(4,400),(5,625)]

-------

And then the slightly more complex version that puts the results one per line:

-------

*Big3> (((id &&& ((* 5) >>> (^ 2)))) <$>) >>> (show <$>) >>> mapM_ putStrLn $ [1..7]

(1,25)

(2,100)

(3,225)

(4,400)

(5,625)

(6,900)

(7,1225)



Okay this may not seem too worthwhile to this point, as we are just doing things to the LIST Monad.. aka the also LIST Functor.

ah yes it is.. and so is the Maybe monad a Functor too.. which leads to a much more wonderful use of the applicatives, as they

don't care too much about the type of functor that they are dealing with..

Here is some more motivation in the dressing of a new operator that (<$$>) which bores down a through two layers of functor to apply a function to the innards of the second one down. Here is the type signature of it:

*Big3> :t (<$$>)

(<$$>)

:: forall a b (f1 :: * -> *) (f :: * -> *).

(Functor f, Functor f1) =>

(a -> b) -> f1 (f a) -> f1 (f b)

so that (a to b) function is applied to the elements of the inner functor {f} which is enclosed in the outer functor {f1}. So for the first set of examples I will use a Maybe (Maybe a):

----

*Big3> (* 4) <$$> Just Nothing

Just Nothing

*Big3> (* 4) <$$> Just (Just 5)

Just (Just 20)

-------



Okay not too impressive, but it does what it advertises ----

Now a bit more interesting, a list of Maybe (Num) that is applied to by an arrow computation.

------

( ---- arrow ---- ) (app) (----List of Maybe Num -------------- )

*Big3> ((+ 3) >>> (* 10)) <$$> [Nothing,Just 3,Just 7,Nothing,Just 9]

[Nothing,Just 60,Just 100,Nothing,Just 120]



This can be prettied up by pulling discarding the Nothings and giving the resulting "a" value of the "Just a"s using catMaybe.



*Big3> (((+ 3) >>> (* 10)) <$$>)

>>> Maybe.catMaybes

$ [Nothing,Just 3,Just 7,Nothing,Just 9]



[60,100,120]



Also have a few more applicative operators that I have conjured up that let me go down to level 3 and 4 and are:



(<$$$>)

:: forall a

b

(f2 :: * -> *)

(f1 :: * -> *)

(f :: * -> *).

(Functor f, Functor f1, Functor f2) =>

(a -> b) -> f2 (f1 (f a)) -> f2 (f1 (f b))



eg:

*Big3> (* 3) <$$$> [[Just 3,Nothing,Just 4],[Nothing],[Just 5,Just 6,Nothing]]

[[Just 9,Nothing,Just 12],[Nothing],[Just 15,Just 18,Nothing]]



This one is a bit dense..but ..will spread it out down page to try and make it easier to read:

*Big3> Maybe.catMaybes $

((

(words <$>) >>>

((\cs -> if length cs < 3 then Nothing else Just cs)<$$>))

) ["follow is a test","As is offer bloat"] >>=

( (++ "ing") <$$>)

["following","testing","offering","bloat ing"]



This one just goes down another level into a fourth layer of functor, and BELIEVE it or NOT, I have used it too.

These can occur in situations of a lookup of a lookup of a perhaps lookup where you could have a result like:

[Nothing, Just Nothing, Just [Just a,Nothing,Just c]]



(<$$$$>)

:: forall a

b

(f3 :: * -> *)

(f2 :: * -> *)

(f1 :: * -> *)

(f :: * -> *).

(Functor f, Functor f1, Functor f2, Functor f3) =>

(a -> b) -> f3 (f2 (f1 (f a))) -> f3 (f2 (f1 (f b)))



--------- That's all for now.. probably more than enough!!

In trying to get a handle on monads, which I was having more then a bit of trouble with for some time, I got so disgusted that I decided to look at the arrow notation, and at least I was able to make use of them, and then I took a look at applicative functors, and the various operators. In doing what I call investigative programming, "playing around with" could be a better way to put it, I came to find that all three could be mixed and matched to make a better soup then just one paradigm alone in some cases. If another person wants to try this, the main thing to remember is that in order to do that each computational unit, HAS to be encapsulated, usually just by a set of parenthesis to keep things in order, or things will blow up with some sort of compiler error message about mismatch, or precedence problems.. but all that can be avoided by a simple surrounding of whichever, arrow, applicative Functor or monad, in use with said parenthesis.I think that some examples will make this much clearer. So I will use a run of the ghci with a ghc extras turned on for --farrows and --ghc-exts and then I fire up a mostly empty module called Big3.lhs that just has the imports of Control.Arrow, Control.Applicative, and Control.Monad, to allow all three of those notations.Standard monadic bind:*Big3> [[2,4,6],[7..13],[10,20..50]] >>= return . fmap (* 3)[[6,12,18],[21,24,27,30,33,36,39],[30,60,90,120,150]]and the same although w/o the return, so leaves unwrapped:*Big3> [[2,4,6],[7..13],[10,20..50]] >>= fmap (* 3)[6,12,18,21,24,27,30,33,36,39,30,60,90,120,150]Now here is the result I was talking about with the mixed usage and a failure to compute due to a not having the individual types of computations enclosed properly. So when I see this type of error message, I immediately know that I have forgotten to slap some parenthesis around some part of the computation to isolate it properly.-----*Big3> [[2,4,6],[7..13],[10,20..100]] >>= ((* 3) ) >>> return