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
|
- 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
|
- 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)
|
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
|
- 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
|
description
|
sweet
|
unsweet
|
if-then-else
|
if x then y else z
|
case x of
True -> y
False -> z
|
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.
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
.
- For more information on layout, see the chapter on Indentation
Notes
- ↑ For types in the Num class, including user-defined ones.
- ↑ Analogous conversions hold for larger tuples.