Reputation: 583
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?
Upvotes: 1
Views: 150
Reputation: 54971
<|>
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 <*
Upvotes: 3
Reputation: 152682
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)
.
Upvotes: 10