I want something like J's fork feature, I guess. Is there any way to do this?
This is, using so-called applicative style,
h <$> f <*> g
using <$> and <*> from Control.Applicative.
An alternative is to lift h into the (->) r applicative functor with
liftA2 h f g
The intuition behind that is that if
h :: a -> b -> c
-- then --
liftA2 h :: (r -> a) -> (r -> b) -> r -> c
so the lifted version takes two functions r -> something instead of the actual somethings, and then feeds an r to get the somethings out of the functions.
The liftA* and the corresponding combination of <$> and <*> are equivalent.
While @kqr has the more practical solution based on the Applicative instance for ((->) a), we can also talk about it in the "pipey" method
+----- f ------+
/ \
<---- h +------< x
\ /
+----- g ------+
which provides a very compositional kind of pointfree program. We'll create this program with tools from Control.Arrow.
First we get the rightmost part of our diagram using a common missing function in Haskell called diag or dup
--+
\
+----- x dup :: x -> (x, x)
/ dup x = (x, x)
--+
then the middle is created using the (***) combinator from Control.Arrow
----- f ----- (***) :: (a -> b) -> (c -> d) -> (a, c) -> (b, d)
f :: (a -> b)
g :: (c -> d)
----- g ----- f *** g :: (a, c) -> (b, d)
then the left side is exactly what uncurry does for us
+-- uncurry :: (a -> b -> c) -> (a, b) -> c
/ h :: (a -> b -> c)
h uncurry h :: (a, b) -> c
\
+--
Then wiring them all together we can erase the x points with a very compositional style.
m :: (a -> b -> c) -> (x -> a) -> (x -> b) -> x -> c
m h f g = uncurry h . (f *** g) . dup
+------ f ----+
/ \
<----- h +-----------< x (eta reduced)
\ /
+------ g ----+
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With