Closed BebeSparkelSparkel closed 6 months ago
The implementations being,
(<$<) :: Functor f => (b -> c) -> (a -> f b) -> a -> f c
bc <$< afb = fmap bc . afb
(>$>) :: Functor f => (a -> f b) -> (b -> c) -> a -> f c
(>$>) = flip (<$<)
Yeah, I don't think so.
It would be helpful to see some examples where these combinators help
@mixphix I don't appreciate your attitude. Especially, since this is basically the exact implementation of the useful infix functions <=<
and >=>
that are already in base shown below.
(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> (a -> m c)
f >=> g = \x -> f x >>= g
(<=<) :: Monad m => (b -> m c) -> (a -> m b) -> (a -> m c)
(<=<) = flip (>=>)
Please elaborate on your rejection.
On Thu, 18 Apr 2024, mixphix wrote:
The implementations being,
(<$<) :: Functor f => (b -> c) -> (a -> f b) -> a -> f c (<$<) = (.)
(>$>) :: Functor f => (a -> f b) -> (b -> c) -> a -> f c (>$>) = flip (.)
Yeah, I don't think so.
The function (b -> c) is applied to the Functor element.
I'd like to remind everyone to remain respectful to each other.
@BebeSparkelSparkel could you possibly explain why you find these combinators particularly useful? There are quite a few combinations of (.)
and fmap
possible, but apparently you feel that these two are more interesting than others. Is there a prior art (e. g., alternative preludes or helper libraries such as extra
and MissingH
)?
@ocharles It is useful for modifying the result of monadic composition. My specific case is
BB.lazyByteString <$< BL.hGet h . fromInteger
reading in n :: Integer
bytes from a file and then wrapping it in a ByteString Builder.
It is also used in
Centril/TDA283-compiler-construction many examples
_sfType <$$> getStructDef (_tIdent typ) >>= mapM compileType >$> LStruct
simplify (SSum xs) = either id SSum $ (factorise <=< sort <$< diff . c extractConst . extractSum . map simplify) xs
chainweb-node Not really sure why they use it but they use it a lot.
@Bodigrim It is possible to use . and fmap together but if a function has arguments it becomes a bit messier
fmap (splitAt 5) . getLines
splitAt 5 <$< getLines
Basically it is good for concluding monaic composition.
It is also used in futurice/futuLog#L25
Just to be clear, this one is (>$>) :: Functor f => (a -> f b) -> c -> a -> f c
, different from your proposal.
chainweb-node Not really sure why they use it but they use it a lot.
I think they use Configuration.Utils.(<$<) :: Functor f => f (a -> b) -> (b -> c) -> f (a -> c)
, again different from what you propose.
It is possible to use
.
andfmap
together but if a function has arguments it becomes a bit messierfmap (splitAt 5) . getLines splitAt <$< getLines
Sorry, I don't quite follow the example. I assume getLines
is Handle -> IO [String]
, in which case fmap (splitAt 5) . getLines :: Handle -> IO ([String], [String])
, but then splitAt <$< getLines
is ill-typed.
@Bodigrim Sorry for not looking at those examples more closely and wasting your time, I'll review them more thoroughly and update it.
Thanks for all your comments. This seems to be a personally useful function and not a community demanded function.
<$<
and>$>
would be use useful functions to have exported fromData.Functor
. There is already a precedence for this syntax with>=>
so it would be intuitive for most.I only see one conflict with the package configuration-tools.