Chinaunix首页 | 论坛 | 博客
  • 博客访问: 13708
  • 博文数量: 2
  • 博客积分: 1461
  • 博客等级: 上尉
  • 技术积分: 50
  • 用 户 组: 普通用户
  • 注册时间: 2009-04-17 10:11
文章分类

全部博文(2)

文章存档

2009年(2)

我的朋友
最近访客

分类:

2009-04-24 21:51:53

语法糖

下面一段摘自:http://hi.baidu.com/kuangxiangjie/blog/item/f20743fb81bf6b106d22ebd1.html
在Wiki里关于语法糖的一些历史介绍:
语法糖(Syntactic sugar),是由Peter J. Landin(和图灵一样的天才人物,是他最先发现了Lambda演算,由此而创立了函数式编程)
创造的一个词语,它意指那些没有给计算机语言添加新功能,而只是对人类来说更“甜蜜“的语法。语法糖往往给程序员提供了更实用的
编码方式,有益于更好的编码风格,更易读。不过其并没有给语言添加什么新东西。

Wiki里提到,在C语言里用a[n]表示*(a+n),用a[n][m]表示*(*(a+n)+m),也是语法糖。
实际上从面向过程到面向对象也是一种语法糖,C语言可以通过它的指针、类型转换,结构实现面向对象的编程风格,
但是C++更进一步的推广了这种风格,更好用了。

按照Wiki的理解,只有计算机硬件指令才不算语法糖,而其他一切利用编译器、汇编器将代码抽象,和自然语言更相近的手段都算语法糖。


现在我们介绍一下 Haskell 中的语法糖,如有错误,请指正,改之

1.缩进

Haskell 也像 C 语言一样可以用大括号 '{}' 和分号 ';' 来构造程序块,但这样的写法会造成程序难以阅读,为了解决这个问题,Haskell 引入了缩进。
注意 Haskell 的缩进不同于 Python 的缩进。在 Python 中,tab/空格 是语法,而 Haskell 中 tab/空格 是定义良好的语法糖,最终会被转换成
括号和分号的程序块的语法。

使用缩进的结构有:let,where,case of,... ? (其他的就不了解了)。在它们之后的缩进都可以转换为括号和分号的程序块语法。

2.List

List 的最终转换如下:

[1, 2, 3, 4] => 1:2:3:4:[]
[1..10] => enumFromTo 1 10
[1, 3..10] => enumFromThenTo 1 3 10
[1..] => enumFrom 1
[1, 3..] => enumFromThen 1 3

Prelude> :t enumFrom
enumFrom :: (Enum a) => a -> [a]
Prelude> :t enumFromTo
enumFromTo :: (Enum a) => a -> a -> [a]
Prelude> :t enumFromThen
enumFromThen :: (Enum a) => a -> a -> [a]
Prelude> :t enumFromThenTo
enumFromThenTo :: (Enum a) => a -> a -> a -> [a]

Prelude> enumFromTo 1 10
[1,2,3,4,5,6,7,8,9,10]
Prelude> enumFromThenTo 1 3 10
[1,3,5,7,9]
Prelude> enumFrom 1
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20
...
...
15732,15733,15Interrupted.

3.String

String 其实也是 List,之所以把它单独列出来,是因为 String 和 List 写法不一样,前者被双引号括住,而后者被中括号括住
String 的最终转换如下:

"abcde" => 'a':'b':'c':'d':'e':[]

4.List Comprehensions

List Comprehensions 等同于 map, filter 函数,但比 map, filter 函数更直观。
List Comprehensions 的最终转换如下:

[ x | x <- aList , f x]
=>
let ok x = if f x
           then [x]
           else []
in concatMap ok aList


[ fm x | x <- aList, ff x]
=>
do
  x <- aList
  guard (ff x)
  return $ fm x

Prelude> :t concatMap
concatMap :: (a -> [b]) -> [a] -> [b]

5.Section

Section 最终会转换为 lambda 函数

(+2) => \x -> x+2
(*2) => \x -> x*2

6. infix/prefix

1 + 2 => (+) 1 2
take 1 [0, 1] => 1 `take` [0, 1]

7. Named Fields

data Configuration =
  Configuration { username       :: String,
                  localhost      :: String,
                  remotehost     :: String,
                  isguest        :: Bool,
                  issuperuser    :: Bool,
                  currentdir     :: String,
                  homedir        :: String,
                  timeconnected  :: Integer
                  }

会转换为:

data Configuration =
  Configuration String              -- user name
                String              -- local host
                String              -- remote host
                Bool                -- is guest?
                Bool                -- is super user?
                String              -- current directory
                String              -- home directory
                Integer             -- time connected
              deriving (Eq, Show)

username :: Configuration -> String
userName (Configuration un _ _ _ _ _ _ _) = un

localhost :: Configuration -> String
localHost (Configuration _ lh _ _ _ _ _ _) = lh

remoteHost :: Configuration -> String
remoteHost (Configuration _ _ rh _ _ _ _ _) = rh

isGuest :: Configuration -> Bool
isGuest (Configuration _ _ _ ig _ _ _ _) = ig

...

hostData (Configuration {localhost=lh,remotehost=rh}) = (lh,rh)

会转换为:

hostData (Configuration _ lh rh _ _ _ _ _) = (lh,rh)

initCFG' =
  Configuration
    { username="nobody",
      localhost="nowhere",
      remotehost="nowhere",
      isguest=False,
      issuperuser=False,
      currentdir="/",
      homedir="/",
      timeconnected=0 }

会转换为:

initCFG = Configuration "nobody" "nowhere" "nowhere" False False "/" "/" 0

8.do
do 也是语法糖

main = do
   putStrLn "Greetings! What is your name?"
   inpStr <- getLine
   putStrLn $ "Welcome to Haskell, " ++ inpStr ++ "!"

将被转换为:

main =
  putStrLn "Greetings! What is your name?" >>
  getLine >>=
  (\inpStr -> putStrLn $ "Welcome to Haskell, " ++ inpStr ++ "!")


还有几个没有提到的,请参阅回帖:
阅读(1723) | 评论(0) | 转发(0) |
0

上一篇:Haskell 中的 partial function

下一篇:没有了

给主人留下些什么吧!~~