Frage

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?

War es hilfreich?

Lösung

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

Andere Tipps

<|> 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 <*
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top