1.5 KiB
Most commonly used Infix Operators have flipped variants, e.g.
- Functions#Composition has
g <<< forf >>> g - function application has
f $ aora # f - Functor has
f <$> aora <#> f - Bind has
f =<< morm >>= f
In general, right-to-left operators tend to be easier to refactor into & out of because they closely mirror the expressions they replace:
map (add 1) maybeNum
-- into
add 1 <$> maybeNum
foo (bar a)
-- into
foo <<< bar
Left-to-right, on the other hand, can read better to humans and plays better with pipelines containing both [[Bind|bind >>=]] and [[Functor|map <#>]].
Consider an expression piping Maybe String to split :: String -> Array String then Data.Array.NonEmpty.fromArray :: Array a -> Maybe (NonEmptyArray a), then toLower each element:
String.toLower
<$> (
Array.NonEmpty.fromArray
=<< String.split "."
<$> mStr
)
We need to wrap the right hand of the last map because the precedence of =<< is 1 (the lowest) and the precedence of <$> is 4.
Written RTL, though, gives:
mStr
<#> String.split "."
>>= Array.NonEmpty.fromArray
<#> String.toLower
This works because <#>'s Precedence (1) is the same as >>=. The lower precedence on flipped map means you'll often need more parentheses wrapping its arguments (..) <#> (..) >>= (..) as opposed to entire expressions .. <$> (.. =<< ..).
Personally, I try to stick to RTL except for expressions including bind.