Jump to content

Haskell/Syntactic sugar

From Wikibooks, open books for an open world

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 | edit source]
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 | edit source]
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 | edit source]
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 | edit source]
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 | edit source]
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 | edit source]
description sweet unsweet
if-then-else
if x then y else z
case x of
  True -> y
  False -> z

Literals

[edit | edit source]

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 | edit source]

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 | edit source]
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.