跳转到内容

Haskell/语法糖

来自维基教科书,开放的书籍,为开放的世界

语法糖 指的是编程语言中任何冗余的语法类型,它对于主语法是冗余的,但(希望)使代码更容易理解或编写。

函数和构造函数

[编辑 | 编辑源代码]
有关更多信息,请参阅关于函数的更多内容章节。
描述 甜的 不甜的
中缀运算符
a `mappend` b
1+2
mappend a b
(+) 1 2
部分
(+2)
(3-)
\x -> x + 2
\x -> 3 - x
一元负号[1]
-x
negate x
元组[2]
(x,y)
(,) x y

函数绑定

[编辑 | 编辑源代码]
有关更多信息,请参阅Haskell/变量和函数章节。
描述 甜的 不甜的
函数定义
f x y = x * y
f = \x y -> x * y
进一步去糖化成
f = \x -> \y -> x * y
模式匹配
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
有关更多信息,请参阅列表和元组列表 II列表 III理解单子/列表MonadPlus章节。
描述 甜的 不甜的
列表
[1,2,3]
1:2:3:[]
进一步去糖化成
(:) 1 ((:) 2 ((:) 3 []))
字符串
"abc"
['a','b','c']
进一步去糖化成
'a':'b':'c':[]
进一步去糖化成
(:) 'a' ((:) 'b' ((:) 'c' []))
算术序列
[1..5]
[1,3..9]
[1..]
[1,3..]
enumFromTo 1 5
enumFromThenTo 1 3 9
enumFrom 1
enumFromThen 1 3
列表推导到函数
[ x | (x,y) <- foos, x < 2 ]
let ok (x,y) = if x < 2 then [x] else []
in concatMap ok foos
列表推导到列表单子函数
[ 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)
描述 甜的 不甜的
创建
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_
模式匹配
getArea Ball {radius = r} = (r**2) * pi
getArea (Ball _ _ r _) = (r**2) * pi
更改值
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 语法

[编辑 | 编辑源代码]
有关更多信息,请参阅理解单子Do 语法章节。
描述 甜的 不甜的
排序
do putStrLn "one"
   putStrLn "two"
putStrLn "one" >>
putStrLn "two"
单子绑定
do x <- getLine
   putStrLn $ "You typed: " ++ x
getLine >>= \x ->
putStrLn $ "You typed: " ++ x
Let 绑定
do let f xs = xs ++ xs
   putStrLn $ f "abc"
let f xs = xs ++ xs
in putStrLn $ f "abc"
最后一行
do x
x

其他结构

[编辑 | 编辑源代码]
描述 甜的 不甜的
if-then-else
if x then y else z
case x of
  True -> y
  False -> z

字面量

[编辑 | 编辑源代码]

Haskell 代码中的数字(如 5)被解释为 fromInteger 5,其中 5 是一个 Integer。这使得字面量可以被解释为 IntegerIntFloat 等。浮点数(如 3.3)也是如此,它们被解释为 fromRational 3.3,其中 3.3 是一个 Rational。GHC 有 OverloadedStrings 扩展,它允许对来自 Data.ByteString 模块的字符串类型(如 StringByteString)进行相同的操作。

类型层

[编辑 | 编辑源代码]

类型 [Int] 等效于 [] Int。这使得它很明显这是一个对 [] 类型构造函数(种类 * -> *)到 Int(种类 *)的应用。

类似地,(Bool, String) 等效于 (,) Bool String,对于更大的元组也是如此。

函数类型具有相同的糖:Int -> Bool 也可以写成 (->) Int Bool

有关布局的更多信息,请参阅缩进章节。

注释

  1. 对于 Num 类中的类型,包括用户定义的类型。
  2. 类似的转换适用于更大的元组。
华夏公益教科书