语法糖
下面一段摘自: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 3Prelude> :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 "/" "/" 08.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 ++ "!")还有几个没有提到的,请参阅回帖:
阅读(1778) | 评论(0) | 转发(0) |