Haskell/Syntactic sugar

Syntactic sugar refers to any redundant type of syntax in a programming language that is redundant to the main syntax but which (hopefully) makes the code easier to understand or write.

Functions and constructors edit

For more information, see the chapter More on functions
description sweet unsweet
infix operators
a `mappend` b
1+2
mappend a b
(+) 1 2
sections
(+2)
(3-)
\x -> x + 2
\x -> 3 - x
unary minus[1]
-x
negate x
tuples[2]
(x,y)
(,) x y

Function Bindings edit

For more information, see the chapter Haskell/Variables_and_functions
description sweet unsweet
function definitions
f x y = x * y
f = \x y -> x * y
further desugared to
f = \x -> \y -> x * y
pattern matching
f []       = 0
f (' ':xs) = f xs
f (x:xs)   = 1 + f xs
f = \l -> case l of
                    []       -> 0
                    (' ':xs) -> f xs
                    (x:xs)   -> 1 + f xs

Lists edit

For more information, see the chapters Lists and tuples, Lists II, Lists III, Understanding monads/List and MonadPlus
description sweet unsweet
lists
[1,2,3]
1:2:3:[]
further desugared to
(:) 1 ((:) 2 ((:) 3 []))
strings
"abc"
['a','b','c']
further desugared to
'a':'b':'c':[]
even furtherly desugared to
(:) 'a' ((:) 'b' ((:) 'c' []))
arithmetic sequences
[1..5]
[1,3..9]
[1..]
[1,3..]
enumFromTo 1 5
enumFromThenTo 1 3 9
enumFrom 1
enumFromThen 1 3
list comprehensions to functions
[ x | (x,y) <- foos, x < 2 ]
let ok (x,y) = if x < 2 then [x] else []
in concatMap ok foos
list comprehensions to list monad functions
[ x | (x,y) <- foos, x < 2 ]

[ (x, bar) | (x,y) <- foos,
              x < 2,
              bar <- bars,
              bar < y ]
foos >>= \(x, y) ->
guard (x < 2) >>
return x

foos >>= \(x, y) -> guard (x < 2) >>
                    bars >>= \bar ->
                    guard (bar < y) >>
                    return (x, bar)
-- or equivalently
do (x, y) <- foos
   guard (x < 2)
   bar <- bars
   guard (bar < y)
   return (x, bar)

Records edit

description sweet unsweet
Creation
data Ball    = Ball
            { x :: Double
            , y :: Double
            , radius :: Double
            , mass :: Double
            }
data Ball   = Ball
              Double
              Double
              Double
              Double

x :: Ball -> Double
x (Ball x_ _ _ _) = x_

y :: Ball -> Double
y (Ball _ y_ _ _) = y_

radius :: Ball -> Double
radius (Ball _ _ radius_ _) = radius_

mass :: Ball -> Double
mass (Ball _ _ _ mass_) = mass_
Pattern matching
getArea Ball {radius = r} = (r**2) * pi
getArea (Ball _ _ r _) = (r**2) * pi
Changing values
moveBall dx dy ball = ball {x = (x ball)+dx, y = (y ball)+dy}
moveBall dx dy (Ball x y a m) = Ball (x+dx) (y+dy) a m

Do notation edit

For more information, see the chapters Understanding monads and do Notation.
description sweet unsweet
Sequencing
do putStrLn "one"
   putStrLn "two"
putStrLn "one" >>
putStrLn "two"
Monadic binding
do x <- getLine
   putStrLn $ "You typed: " ++ x
getLine >>= \x ->
putStrLn $ "You typed: " ++ x
Let binding
do let f xs = xs ++ xs
   putStrLn $ f "abc"
let f xs = xs ++ xs
in putStrLn $ f "abc"
Last line
do x
x

Other constructs edit

description sweet unsweet
if-then-else
if x then y else z
case x of
  True -> y
  False -> z

Literals edit

A number (such as 5) in Haskell code is interpreted as fromInteger 5, where the 5 is an Integer. This allows the literal to be interpreted as Integer, Int, Float etc. Same goes with floating point numbers such as 3.3, which are interpreted as fromRational 3.3, where 3.3 is a Rational. GHC has OverloadedStrings extension, which enables the same behaviour for string types such as String and ByteString varieties from the Data.ByteString modules.

Type level edit

The type [Int] is equivalent to [] Int. This makes it obvious it is an application of [] type constructor (kind * -> *) to Int (kind *).

Analogously, (Bool, String) is equivalent to (,) Bool String, and the same goes with larger tuples.

Function types have the same type of sugar: Int -> Bool can also be written as (->) Int Bool.

Layout edit

For more information on layout, see the chapter on Indentation

Notes

  1. For types in the Num class, including user-defined ones.
  2. Analogous conversions hold for larger tuples.