Question

Regarding Control.Applicative, If I have the following expression:

f = (expr1 <|> expr2) <* expr3

Are the brackets necessary? That is, will expr3 get evaluated (and thrown away) regardless of which branch is taken?

Was it helpful?

Solution

You can ask ghci for precedence information:

Prelude Control.Applicative> :i <|>
class Applicative f => Alternative f where
  ...
  (<|>) :: f a -> f a -> f a
  ...
    -- Defined in `Control.Applicative'
infixl 3 <|>
Prelude Control.Applicative> :i <*
class Functor f => Applicative f where
  ...
  (<*) :: f a -> f b -> f a
    -- Defined in `Control.Applicative'
infixl 4 <*

The relevant bits there are these two lines:

infixl 3 <|>
infixl 4 <*

Since <* has a higher precedence (4), it binds tighter; so yes, the brackets are needed to prevent that from being parsed as expr1 <|> (expr2 <* expr3).

OTHER TIPS

<|> has a precedence of 3; <* of 4. So the parentheses are required.

$ ghci
λ import Control.Applicative
λ :info <|>
class Applicative f => Alternative f where
  ...
  (<|>) :: f a -> f a -> f a
  ...
    -- Defined in `Control.Applicative'
infixl 3 <|>
λ :info <*
class Functor f => Applicative f where
  ...
  (<*) :: f a -> f b -> f a
    -- Defined in `Control.Applicative'
infixl 4 <*
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top