类型瞥一眼
在 REPL 中,可以使用 :type 'a' 查看 'a'
的类型。
ghci> :type 'a'
'a' :: Char可见 'a' 的类型即为 Char。
ghci> :type "Hello"
"Hello" :: String而 "Hello" 的类型即为 String。
实质上,String 只是一个类型别名(type alias),它等同于
[Char],亦即 Char 列表。
ghci> :info String
type String :: *
type String = [Char]
-- Defined in ‘GHC.Base’打印
可以使用 print 打印很多类型:
ghci> print 14
14
ghci> print 14.2
14.2
ghci> print 'a'
'a'
ghci> print "str"
"str"而 putStrLn 和 putStr
只用于打印字符串:
ghci> putStrLn "114514"
114514
ghci> putStr "114514"
114514ghci>显然的,前者在字符串末尾添加换行符。
拼接
-- concat.hs
myGreeting :: String
myGreeting = "hello" ++ " world!"
hello :: String
hello = "hello"
world :: String
world = "world"
main :: IO ()
main = do
putStrLn myGreeting
putStrLn secondGreeting
where
secondGreeting = concat [hello, " ", world]❯ ghc ./*.hs && ./concat
Linking concat ...
hello world!
hello world可以使用 :: 标注类型,对于 top-level
声明,这是必要的。
拼接字符串可使用 ++ 或 concat。
作用域
-- Scope.hs
module Scope where
topLevelFunc :: Integer -> Integer
topLevelFunc x =
x + woot + topLevelValue
where woot :: Integer
woot = 10
topLevelValue :: Integer
topLevelValue = 5woot 仅在 topLevelFunc 函数体中可以访问。而
topLevelFunc 和 topLevelValue
允许模块内,或导入该模块的作用域使用。where 和
let 都引入了本地绑定作用域。
拼接函数的类型
不妨查看 (++) 和 concat 的类型:
-- 接收两个列表,输出为一个列表
(++) :: [a] -> [a] -> [a]
-- 接收一组列表,输出为一个列表
concat :: [[a]] -> [a]
-- 当然如果使用 GHC 7.10 或更高, concat 的类型长这样:
concat :: Foldable t => t [a] -> [a]
-- 目前将 Foldable t => t [a] 看作 [[a]] 即可这两个函数都能不同的类型,但同一函数中的类型 a
必须一致。这正是 Haskell 的重要特性——多态性(polymorphism)。
"hello" ++ " Chris" -- OK
"hello" ++ [1, 2, 3] -- Error列表函数
因为 String 是特定类型的列表。因此,对于
String 也可以使用标准的列表函数。
例如,(:) 操作符,亦称 cons:
'c' : "hris" -- "chris"
'P' : "" -- "P-- head
head "Snake" -- "S"
-- tail
tail "Snake" -- "nake"
-- take
take 0 "Snake" -- ""
take 1 "Snake" -- "S"
take 3 "Snake" -- "Sna"
take 6 "Snake" -- "Snake"
-- drop
drop 3 "Snake" -- "ke"
drop 114514 "Snake" -- ""
drop 1 "Snake" -- "nake"
-- (++)
"Pine" ++ "apple" -- "Pineapple"
-- !!
"Pineapple" !! 0 -- "P"
"Pineapple" !! 4 -- "a"请注意,以上函数是不安全的(unsafe)。因为它们不考虑全部情况,并会抛出异常:
ghci> head ""
*** Exception: Prelude.head: empty list
ghci> "0123" !! 5
*** Exception: Prelude.!!: index too large以上,即为基本的字符串处理。
