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