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 something
s, and then feeds an r
to get the something
s 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