# Basic Syntax Extensions

30 Sep 2013

These extensions simply enhance Haskell's core syntax without providing any actually new semantic features.

TEMPORARY NOTE: Some of the extensions described by this page are not currently supported by the School of Haskell, which uses a version of the Haskell Platform that is not the current one. Please note that these guides are written with the current Haskell Platform and/or the current GHC in mind.

# `PostfixOperators`

The `PostfixOperators` extension allows you some slight extra leeway with Haskell's operator section syntax. Normally, when you write, for example:

``(4 !)``

it expands into:

``\x -> 4 ! x``

or, equivalently:

``\x -> (!) 4 x``

`PostfixOperators` instead expands this left section into:

``(!) 4``

which may look the same to you initially, and it behaves the same way where they both compile, but the new form allows GHC to be somewhat more lenient about the type of `(!)`.

For example, `(!)` can now be the factorial function and have the type:

``(!) :: Integer -> Integer``

Unfortunately, `PostfixOperators` does not allow you to define operators in postfix fashion, it just allows you to use them that way.

Try it out!

``````{-# LANGUAGE PostfixOperators #-}

(!) :: Integer -> Integer
(!) n | n == 0    = 1
| n >  0    = n * ((n - 1) !)
| otherwise = error "factorial of a negative number"

main = print (4 !)``````

# `TupleSections`

The `TupleSections` extension allows you to omit values from the tuple syntax, unifying the standard tuple sugar with the tuple constructor syntax to form one generalized syntax for tuples.

Normally, tuples are constructed with the standard tuple sugar, which looks like this:

``(1, "hello", 6.5, Just (), [5, 5, 6, 7])``

This could be considered shorthand for the following explicit tuple constructor use:

``(,,,,) 1 "hello" 6.5 (Just ()) [5, 5, 6, 7]``

However, the explicit tuple constructor `(,,,,)` could just as easily be considered section sugar for tuples, expanding to:

``\v w x y z -> (v, w, x, y, z)``

Looking at it this way allows us to ask, "Why can't we partially section a tuple?" After all, `(+)` is valid, `(,)` is valid, and `(1 +)` is valid, but `(1,)` is not valid. The `TupleSections` extension fixes this oversight.

With `TupleSections` you can now write, for example:

``(1, "hello",, Just (),)``

and have it mean the same as

``\x y -> (1, "hello", x, Just (), y)``

Try it out!

``````{-# LANGUAGE TupleSections #-}

main = print \$ map (1, "hello", 6.5,, [5, 5, 6, 7]) [Just (), Nothing]``````

# `PackageImports`

Let's say you want to import module `Data.Module.X` from package `package-one`, but `package-two` is also installed and also contains a module named `Data.Module.X`. You could try to mess with package hiding, either manually or through cabal, but sometimes you might want some other module from `package-two`, so hiding it is not an option.

Enter the `PackageImports` extension. Rather than writing:

``import Data.Module.X``

and hoping that GHC gets the one from the right package, `PackageImports` lets you write:

``import "package-one" Data.Module.X``

and explicitly specify the package you want to import that module from. You can even import from a specific package version:

``import "package-one-0.1.0.1" Data.Module.X``

You can use `PackageImports` in combination with any other variant of the `import` syntax, and you can use both package-qualified imports and regular imports in the same file.

Try it out!

``````{-# LANGUAGE PackageImports #-}
import Data.Monoid (Sum(..))
import "base" Data.Foldable (foldMap)
import qualified "containers" Data.Map as Map

main = print . getSum . foldMap Sum \$ Map.fromList [(1, 2), (3, 4)]``````

# `OverloadedStrings`

By default, Haskell's numeric literals are polymorphic over `Num` (in the case of integer literals) or `Fractional` (in the case of decimal literals). That is, you can write:

``````a :: Int
a = 1

b :: Double
b = 1

c :: Float
c = 3.5

d :: Rational
d = 3.5``````

and it just works as expected.

String literals, on the other hand, are always of type `String`, and are not polymorphic at all. The `OverloadedStrings` extension corrects this, making string literals polymorphic over the `IsString` type class, which is found in the `Data.String` module in the `base` package. That is, you can write:

``````a :: String
a = "hello"

b :: Text
b = "hello"``````

`OverloadedStrings` also adds `IsString` to the list of defaultable type classes, so you can use types like `String`, `Text`, and `Bytestring` in a `default` declaration.

Try it out!

``````{-# LANGUAGE OverloadedStrings #-}
import qualified Data.Text.IO as T

main = do putStrLn   "Hello as String!"
T.putStrLn "Hello as Text!"``````

# `UnicodeSyntax`

With the `UnicodeSyntax` extension (along with the `base-unicode-symbols` package and the `containers-unicode-symbols` package on Hackage), you can use Unicode alternatives to many of the standard operators. The `UnicodeSyntax` extension itself handles just the operators and symbols that are built into the Haskell language, whereas the `base-unicode-symbols` package handles the operators and functions provided by the `base` package and the `containers-unicode-symbols` package handles the operators and functions provided by the `containers` package.

For the package-based Unicode symbols, you need to import the appropriate syntax module. For example, if you wanted to use Unicode symbols when working with `Data.Map`, you would import `Data.Map.Unicode`.

The various aliased ASCII syntax pieces, values, and types, along with their `UnicodeSyntax` equivalents, are as follows:

• From the `UnicodeSyntax` Extension
• `::` = `∷`
• `=>` = `⇒`
• `forall` = `∀`
• `->` = `→`
• `<-` = `←`
• `-<` = `⤙`
• `>-` = `⤚`
• `-<<` = `⤛`
• `>>-` = `⤜`
• `*` = `★`
• From the `base-unicode-symbols` Package
• From the `Prelude.Unicode` Module
• Values
• `not` = `(¬)`
• `(&&)` = `(∧)`
• `(||)` = `(∨)`
• `(==)` = `(≡)`
• `(/=)` = `(≠)` = `(≢)`
• `pi` = `π`
• `(/)` = `(÷)`
• `(*)` = `(⋅)`
• `(.)` = `(∘)`
• `(++)` = `(⧺)`
• `elem` = `(∈)`
• `notElem` = `(∉)`
• `undefined` = `(⊥)`
• Types
• `Integer` = `ℤ`
• `Rational` = `ℚ`
• From the `Control.Applicative.Unicode` Module
• `(<*>)` = `(⊛)`
• `empty` = `(∅)`
• From the `Control.Arrow.Unicode` Module
• `(>>>)` = `(⋙)`
• `(<<<)` = `(⋘)`
• `(***)` = `(⁂)`
• `(+++)` = `(⧻)`
• `(|||)` = `(⫴)`
• From the `Control.Category.Unicode` Module
• `(.)` = `(∘)`
• `(>>>)` = `(⋙)`
• `(<<<)` = `(⋘)`
• From the `Control.Monad.Unicode` Module
• `(>>=)` = `(≫=)`
• `(>>)` = `(≫)`
• `(=<<)` = `(=≪)`
• From the `Data.Bool.Unicode` Module
• `(&&)` = `(∧)`
• `(||)` = `(∨)`
• `not` = `(¬)`
• From the `Data.Eq.Unicode` Module
• `(==)` = `(≡)`
• `(/=)` = `(≠)` = `(≢)`
• From the `Data.Foldable.Unicode` Module
• `elem` = `(∈)` = `flip (∋)`
• `notElem` = `(∉)` = `flip (∌)`
• From the `Data.Function.Unicode` Module
• `(.)` = `(∘)`
• From the `Data.List.Unicode` Module
• `(++)` = `(⧺)`
• `elem` = `(∈)` = `flip (∋)`
• `notElem` = `(∉)` = `flip (∌)`
• `union` = `(∪)`
• `(\\)` = `(∖)`
• `\x y -> union (x \\ y) (y \\ x)` = `(∆)`
• `intersect` = `(∩)`
• From the `Data.Monoid.Unicode` Module
• `mempty` = `(∅)`
• `mappend` = `(⊕)`
• From the `Data.Ord.Unicode` Module
• `<=` = `≤` = `≯`
• `>=` = `≥` = `≮`
• From the `containers-unicode-symbols` Package
• From the `Data.Sequence.Unicode` Module
• `empty` = `(∅)`
• `(<|)` = `(⊲)`
• `(|>)` = `(⊳)`
• `(><)` = `(⋈)`
• From the `Data.Set.Unicode` Module
• `member` = `(∈)` = `flip (∋)`
• `notMember` = `(∉)` = `flip (∌)`
• `empty` = `(∅)`
• `union` = `(∪)`
• `difference` = `(∖)`
• `\x y -> union (difference x y) (difference y x)` = `(∆)`
• `intersection` = `(∩)`
• `isSubsetOf` = `(⊆)` = `flip (⊇)`
• `\x y -> not (isSubsetOf x y)` = `(⊈)` = `flip (⊉)`
• `isProperSubsetOf` = `(⊂)` = `flip (⊃)`
• `\x y -> not (isProperSubsetOf x y)` = `(⊄)` = `flip (⊅)`
• From the `Data.Map.Unicode` Module
• `member` = `(∈)` = `flip (∋)`
• `notMember` = `(∉)` = `flip (∌)`
• `empty` = `(∅)`
• `union` = `(∪)`
• `difference` = `(∖)`
• `\x y -> union (difference x y) (difference y x)` = `(∆)`
• `intersection` = `(∩)`
• From the `Data.Map.Lazy.Unicode` Module
• `member` = `(∈)` = `flip (∋)`
• `notMember` = `(∉)` = `flip (∌)`
• `empty` = `(∅)`
• `union` = `(∪)`
• `difference` = `(∖)`
• `\x y -> union (difference x y) (difference y x)` = `(∆)`
• `intersection` = `(∩)`
• From the `Data.Map.Strict.Unicode` Module
• `member` = `(∈)` = `flip (∋)`
• `notMember` = `(∉)` = `flip (∌)`
• `empty` = `(∅)`
• `union` = `(∪)`
• `difference` = `(∖)`
• `\x y -> union (difference x y) (difference y x)` = `(∆)`
• `intersection` = `(∩)`
• From the `Data.IntSet.Unicode` Module
• `member` = `(∈)` = `flip (∋)`
• `notMember` = `(∉)` = `flip (∌)`
• `empty` = `(∅)`
• `union` = `(∪)`
• `difference` = `(∖)`
• `\x y -> union (difference x y) (difference y x)` = `(∆)`
• `intersection` = `(∩)`
• `isSubsetOf` = `(⊆)` = `flip (⊇)`
• `\x y -> not (isSubsetOf x y)` = `(⊈)` = `flip (⊉)`
• `isProperSubsetOf` = `(⊂)` = `flip (⊃)`
• `\x y -> not (isProperSubsetOf x y)` = `(⊄)` = `flip (⊅)`
• From the `Data.IntMap.Unicode` Module
• `member` = `(∈)` = `flip (∋)`
• `notMember` = `(∉)` = `flip (∌)`
• `empty` = `(∅)`
• `union` = `(∪)`
• `difference` = `(∖)`
• `\x y -> union (difference x y) (difference y x)` = `(∆)`
• `intersection` = `(∩)`
• From the `Data.IntMap.Lazy.Unicode` Module
• `member` = `(∈)` = `flip (∋)`
• `notMember` = `(∉)` = `flip (∌)`
• `empty` = `(∅)`
• `union` = `(∪)`
• `difference` = `(∖)`
• `\x y -> union (difference x y) (difference y x)` = `(∆)`
• `intersection` = `(∩)`
• From the `Data.IntMap.Strict.Unicode` Module
• `member` = `(∈)` = `flip (∋)`
• `notMember` = `(∉)` = `flip (∌)`
• `empty` = `(∅)`
• `union` = `(∪)`
• `difference` = `(∖)`
• `\x y -> union (difference x y) (difference y x)` = `(∆)`
• `intersection` = `(∩)`

Try it out!

``````{-# LANGUAGE UnicodeSyntax #-}
import Data.List.Unicode ((∪))
import qualified Data.Map as M
import Data.Map.Unicode ((∆))

main ∷ IO ()
main = do print \$ [1, 2, 3] ∪ [1, 3, 5]
print \$ M.fromList [(1, 2), (3, 4)] ∆ M.fromList [(3, 4), (5, 6)]``````

# `RecursiveDo` and `DoRec`

The `RecursiveDo` extension (and its deprecated synonym `DoRec`) enables syntactic sugar for value recursion in a monadic context. "What on Earth does that mean?" you might ask. To explain, let's take a look at how `let` behaves in Haskell.

`let` in Haskell allows lazy recursion; that is, you can write:

``````main = print \$
-- show
let x = fst y
y = (3, x)
in  snd y
-- /show``````

However, `do` in Haskell does not allow lazy recursion; in fact, it doesn't allow recursion at all. If you try to write a recursive binding in do notation, it will fail; for example, the following code will cause an error that complains about `y` not being in scope:

``````{-# LANGUAGE StandaloneDeriving #-}

deriving instance (Show a) => Show (Identity a)

main = print ((
-- show
do x <- return \$ fst y
y <- return (3, x)
return \$ snd y
-- /show
) :: Identity Integer)``````

However, sometimes we want to be able to use value recursion but still need to be within a monad. The `MonadFix` type class, from the `Control.Monad.Fix` module in the `base` package, provides an `mfix` function that helps us do exactly that, but the results, while they work, are not very pretty:

``````{-# LANGUAGE StandaloneDeriving #-}

deriving instance (Show a) => Show (Identity a)

main = print ((
-- show
do y <- mfix \$ \y0 -> do x <- return \$ fst y0
y1 <- return (3, x)
return y1
return \$ snd y
-- /show
) :: Identity Integer)``````

The `RecursiveDo` extension provides sugar for using `mfix` this way, so that the previous example can be equivalently rewritten as:

``````{-# LANGUAGE RecursiveDo, StandaloneDeriving #-}

deriving instance (Show a) => Show (Identity a)

main = print ((
-- show
mdo x <- return \$ fst y
y <- return (3, x)
return \$ snd y
-- /show
) :: Identity Integer)``````

`RecursiveDo` also provides a second type of syntactic sugar for `mfix` that uses the `rec` keyword instead of the `mdo` keyword. The `rec`-based sugar is somewhat more direct and "low-level" than the `mdo`-based sugar. In terms of the `rec` sugar, our running example is expressed as:

``````{-# LANGUAGE RecursiveDo, StandaloneDeriving #-}

deriving instance (Show a) => Show (Identity a)

main = print ((
-- show
do rec x <- return \$ fst y
y <- return (3, x)
return \$ snd y
-- /show
) :: Identity Integer)``````

The two types of sugar are subtly different in meaning, and the difference has to do with something called segmentation.

When GHC encounters a `let` binding, rather than naïvely binding all the variables at once, it will divide (or segment) them into minimal mutually-dependent groups. For example, take this expression:

``````let x = 1
y = (x, z)
z = fst y
v = snd w
w = (v, y)
in  (snd y, fst w)``````

Instead of just binding everything in a single group, GHC improves the code's efficiency somewhat by treating it as though you'd actually written something like:

``````let x = 1
in  let y = (x, z)
z = fst y
in  let v = snd w
w = (v, y)
in  (snd y, fst w)``````

In a pure `let` binding, the only way this might matter is performance; the semantics of the code is guaranteed to not change. However, segmenting monadic code might produce unexpected results, because `mfix` has to deal with the monadic context somehow during the value recursion, and segmenting a set of bindings into minimal groups could potentially change the meaning of the code.

Only `mdo` segments its bindings. `rec` does no segmentation at all, instead translating to calls to `mfix` exactly where you put `rec`s in the original code. This means that, in the following example, the first two of the following three expressions are equivalent to each other, but the third one is not equivalent to either of the first two:

``````-- | expression 1 (equivalent to expression 2)
mdo x <- return 1
y <- return \$ (x, z)
z <- return \$ fst y
v <- return \$ snd w
w <- return (v, y)
return (snd y, fst w)

-- | expression 2 (equivalent to expression 1)
do x <- return 1
rec y <- return \$ (x, z)
z <- return \$ fst y
rec v <- return \$ snd w
w <- return (v, y)
return (snd y, fst w)

-- | expression 3 (not equivalent to expression 1 or expression 2)
do rec x <- return 1
y <- return \$ (x, z)
z <- return \$ fst y
v <- return \$ snd w
w <- return (v, y)
return (snd y, fst w)``````

Both expression 1 and expression 2 translate roughly to:

``````do x <- return 1
(y, z) <- mfix \$ \(y0, z0) -> do y1 <- return \$ (x, z0)
z1 <- return \$ fst y0
return (y1, z1)
(v, w) <- mfix \$ \(v0, w0) -> do v1 <- return \$ snd w0
w1 <- return (v0, y)
return (v1, w1)
return (snd y, fst w)``````

On the other hand, expression 3 translates roughly to:

``````do (x, y, z, v, w) <- mfix \$ \(x0, y0, z0, v0, w0) -> do x1 <- return 1
y1 <- return \$ (x0, z0)
z1 <- return \$ fst y0
v1 <- return \$ snd w0
w1 <- return (v0, y0)
return (x1, y1, z1, v1, w1)
return (snd y, fst w)``````

Try it out!

``````{-# LANGUAGE RecursiveDo #-}

comp = do x0 <- get
modify (+1)
x1 <- get
rec y <- return \$ (x0, fst z)
z <- return \$ (x1, fst y)
liftIO \$ print (y, z)
put 3
return (y, z)

main = do v <- runStateT comp 1
print v``````

# `LambdaCase`

The `LambdaCase` extension is very simple. Any time you would otherwise have written:

``\x -> case x of ...``

``\case ...``

which is both shorter and doesn't bind `x` as a name. The Layout Rule works as usual with `LambdaCase`, so, for example:

``````[Just 1, Just 2, Nothing, Just 3] `forM_` \x -> case x of
Just v  -> putStrLn ("just a single" ++ show v)
Nothing -> putStrLn "no numbers at all"``````

can be shortened to:

``````[Just 1, Just 2, Nothing, Just 3] `forM_` \case
Just v  -> putStrLn ("just a single" ++ show v)
Nothing -> putStrLn "no numbers at all"``````

Try it out!

``````{-# LANGUAGE LambdaCase #-}

-- | should print:
--   @["just a single 1","just a single 2","no numbers at all","just a single 3"]@
main = [Just 1, Just 2, Nothing, Just 3] `forM_` \case
Just v  -> putStrLn ("just a single" ++ show v)
Nothing -> putStrLn "no numbers at all"``````

# `MultiWayIf`

The `MultiWayIf` extension allows you to use the full power of Haskell's guard syntax in an `if` expression. For example, this code:

``````if x == 1
then "a"
else if y < 2
then "b"
else "c"``````

can be rewritten as:

``````if | x == 1    -> "a"
| y <  2    -> "b"
| otherwise -> "d"``````

which is not only much nicer, but it doesn't affect layout, instead allowing the previous layout to remain unchanged.

Try it out!

``````{-# LANGUAGE MultiWayIf #-}

fn :: Int -> Int -> String
fn x y = if | x == 1    -> "a"
| y <  2    -> "b"
| otherwise -> "c"

-- | should print:
--   @c@
main = putStrLn \$ fn 3 4``````