Domanda

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?

È stato utile?

Soluzione

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).

Altri suggerimenti

<|> 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 <*
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top