0

Below I've produced what I believe to be a summary of the standard $ like operators for various classes in Haskell. There's some gaps however. Following the applicative pattern, you would think those operators would be $$ and <$$> however I didn't see operators like that on Hoogle or Hayoo. Could someone fill in the gaps with the most commonly used operators for such gaps?

 | Function first | Op | Function second | Op |
----------------------------------------------------------------------------------
| Plain | (a -> b) -> a -> b | $ | a -> (a -> b) -> b | |
| Functor | (a -> b) -> f a -> f b | <$> | f a -> (a -> b) -> f b | |
| Applicative | f (a -> b) -> f a -> f b | <*> | f a -> f (a -> b) -> f b | <**> |
| Monad | (a -> m b) -> m a -> m b | =<< | m a -> (a -> m b) -> m b | >>= |
-----------------------------------------------------------------------------------
asked Dec 12, 2014 at 2:27
1
  • 1
    taking a cue from F#, sometimes you see |> defined for a -> (a -> b) -> b. Commented Dec 12, 2014 at 2:45

2 Answers 2

4

There isn't one sadly. People usually use the left column with . instead of separate operators. I sometimes see people use

|> :: a -> (a -> b) -> b

as a pipe line-esque operator F# and OCaml like. Generally, however, people use . instead so

 a |> f |> g

is written as

 g . f $ a

This also applies to <$>

 a |$> f |$> g

could be written as

 g . f <$> a

This is actually faster (by a factor of 2x) since <$> can be quite expensive for large collections.

answered Dec 12, 2014 at 3:06
3
  • 1
    I've seen your |> spelled as # in a few libraries. Also, I'm surprised that GHC isn't capable of rewriting a |$> f |$> g as g . f <$> a, since it's one of the functor laws. Commented Dec 12, 2014 at 5:39
  • 1
    @BenjaminHodgson GHC can't assume that you actually obey the type class's laws though. Somewhere, some (probably mean) person has a codebase relying on a broken functor :/ Commented Mar 13, 2015 at 17:55
  • @jozefg Is there an optimization setting that makes GHC assume all laws hold? Because as long as you aren't using a bad library / relying on unlawful behavior (bottoms / the exact rounding error you get from floating point math) the program should work just fine (right?). Commented Mar 26, 2016 at 22:46
3

The lens package provides these operators:

(&) :: a -> (a -> b) -> b

(<&>) :: Functor f => f a -> (a -> b) -> f b

From the lens documentation on (&):

This is the flipped version of ($), which is more common in languages like F# as (|>) where it is needed for inference. Here it is supplied for notational convenience and given a precedence that allows it to be nested inside uses of ($).

Since 7.8 (&) can be found in Data.Function too.

answered Mar 13, 2015 at 17:19

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.