In [ ]:
-- 一般包含函数/类型/类型类, 允许到处部分定义
-- prelude为自动导入模块,
In [1]:
-- import必须放到函数定义前
-- import回直接食用全局命名空间
-- 使用hoogle查询文档
In [2]:
-- ghci中使用 :m + 导入模块
In [3]:
:m + Data.List
In [5]:
-- 一次import多个
:m + Data.List Data.Map Data.Set
In [6]:
-- 部分导入
import Data.List (nub, sort)
In [7]:
-- import hide
import Data.List hiding (nub)
In [9]:
-- 限定导入, 需要使用前缀访问
import qualified Data.Map
In [10]:
-- 限定导入别名
import qualified Data.Map as M
In [12]:
words "hey these are the words in the sentence"
In [13]:
words "hey these are the words in this sentence"
In [14]:
group [1,1,1,1, 2,2,2,2,2,2, 3,3]
In [15]:
group ["boom", "bip", "bip", "boom", "boom"]
In [16]:
sort [5,4,3,7,2,1]
In [19]:
sort ["boom", "bip", "bip", "boom", "boom"]
In [3]:
import Data.List
wordNums :: String -> [(String, Int)]
wordNums = map (\ws -> (head ws, length ws)) . group . sort . words
In [2]:
-- use this to unload import module
:m -Data.Set -Data.Map
In [4]:
import Data.List
wordNums xs = map (\ws -> (head ws, length ws)) . group . sort . words
In [7]:
:t wordNums
In [8]:
wordNums xs = map (\ws -> (head ws, length ws)) . group . sort . words
In [9]:
"hawaii" `isPrefixOf` "hawaii joe"
In [10]:
"haha" `isPrefixOf` "ha"
In [11]:
"ha" `isPrefixOf` "ha"
In [12]:
any (> 4) [1, 2, 3]
In [13]:
any (=='F') "Frank Sobotka"
In [14]:
any (\x -> x > 5 && x < 10) [1, 4, 11]
In [15]:
import Data.List
In [18]:
isIn :: (Eq a) => [a] -> [a] -> Bool
needle `isIn` haystack = any (needle `isPrefixOf`) (tails haystack)
In [19]:
"art" `isIn` "party"
In [20]:
[1, 2] `isIn` [1, 2, 3]
In [22]:
import Data.Char
ord 'a'
In [23]:
chr 97
In [24]:
map ord "abcdefgh"
In [25]:
import Data.Char
encode :: Int -> String -> String
encode offset msg = map (\c -> chr $ ord c + offset) msg
In [26]:
encode 3 "hey mark"
In [28]:
encode 5 "please instruct your men"
In [29]:
encode 1 "to party hard"
In [30]:
decode :: Int -> String -> String
decode shift msg = encode (negate shift) msg
In [31]:
decode 3 "kh|#pdun"
In [32]:
decode 5 "uqjfxj%nsxywzhy%~tzw%rjs"
In [33]:
decode 1 "up!qbsuz!ibse"
In [34]:
-- 严格左折叠
-- foldl会延时计算,遇到大list时会溢出。可以使用Data.List里的fold1(非延时计算)
In [35]:
foldl (+) 0 (replicate 100 1)
In [37]:
-- why not fails????
foldl (+) 0 (replicate 10000000 1)
In [39]:
foldl' (+) 0 (replicate 10000000 1)
In [40]:
-- 寻找酷数
digitToInt '2'
In [41]:
digitToInt 'F'
In [43]:
-- this would raise
digitToInt 'z'
In [44]:
import Data.Char
import Data.List
digitSUm :: Int -> Int
digitSUm = sum . map digitToInt . show
In [46]:
-- Data.List find 找list中第一个满足条件的元素
:t find
In [48]:
-- 使用maybe表示可能失败的计算, Nothing表示空, Just
Nothing
In [49]:
Just "Hey"
In [50]:
Just 3
In [51]:
:t Just "hey"
In [52]:
:t Just True
In [53]:
find (> 4) [3, 4, 5, 6, 7]
In [54]:
find odd [2, 4, 6, 8, 9]
In [55]:
find (=='z') "mjolnir"
In [57]:
firstTo40 :: Maybe Int
firstTo40 = find (\x -> digitSUm x == 40) [1..]
In [58]:
firstTo40
In [62]:
firstTo :: Int -> Maybe Int
firstTo n = find (\x -> digitSUm x == n) [1..]
In [63]:
firstTo 40
In [64]:
firstTo 1
In [65]:
firstTo 13
In [66]:
-- 关联列表, 映射map
playBook = [("betty", "555"), ("bonnie", "452"), ("patsy", "493")]
In [68]:
findKey :: (Eq k) => k -> [(k, v)] -> v
findKey key xs = snd . head . filter (\(k, v) -> key == k) $ xs
In [71]:
-- not raise while empty list
findKey :: (Eq k) => k -> [(k, v)] -> Maybe v
findKey key [] = Nothing
findKey key ((k, v):xs)
| key == k = Just v
| otherwise = findKey key xs
In [72]:
-- fold version
findKey :: (Eq k) => k -> [(k, v)] -> Maybe v
findKey key xs = foldr (\(k,v) acc -> if key == k then Just v else acc) Nothing xs
In [75]:
findKey "penny" playBook
In [76]:
findKey "betty" playBook
In [77]:
findKey "wilma" playBook
In [78]:
-- Data.Map实现了Map
import qualified Data.Map as Map
In [81]:
Map.fromList [(3, "shoes"), (4, "trees"), (9, "bees")]
In [82]:
Map.fromList [("jay", "landsman"), ("jummy", "mcnulty"), ("kima", "greggs")]
In [83]:
-- key重复,旧值被忽略
Map.fromList [("MS", 1), ("MS", 2), ("MS", 3)]
In [84]:
:t Map.fromList
In [86]:
import qualified Data.Map as Map
phoneBook :: Map.Map String String
phoneBook = Map.fromList $
[("betty", "555"), ("bonnie", "452"), ("patsy", "493"), ("lucille", "205")]
In [87]:
:t Map.lookup
In [88]:
Map.lookup "betty" phoneBook
In [90]:
Map.lookup "wendy" phoneBook
In [91]:
Map.lookup "grace" phoneBook
In [92]:
:t Map.insert
In [93]:
let newBook = Map.insert "grace" "341" phoneBook
In [95]:
Map.lookup "grace" newBook
In [96]:
:t Map.size
In [97]:
Map.size phoneBook
In [98]:
Map.size newBook
In [99]:
string2digits :: String -> [Int]
string2digits = map digitToInt . filter isDigit
In [100]:
string2digits "982-12312"
In [101]:
let intBook = Map.map string2digits phoneBook
In [103]:
:t intBook
In [104]:
Map.lookup "betty" intBook
In [105]:
-- Map.fromListWith
phoneBookToMap :: (Ord k) => [(k, String)] -> Map.Map k String
phoneBookToMap xs = Map.fromListWith add xs
where add number1 number2 = number1 ++ ", " ++ number2
In [106]:
phoneBook = [("betty", "555"), ("betty", "432")]
In [107]:
phoneBookToMap phoneBook
In [109]:
Map.lookup "betty" $ phoneBookToMap phoneBook
In [111]:
phoneBookToMap :: (Ord k) => [(k, a)] -> Map.Map k [a]
phoneBookToMap xs = Map.fromListWith (++) $ map (\(k, v) -> (k, [v])) xs
In [113]:
Map.lookup "betty" $ phoneBookToMap phoneBook
In [117]:
Map.fromListWith max [(2,3), (2,5), (2,100), (3, 29)]
In [115]:
Map.fromListWith (+) [(2, 3), (2,5), (2,100), (3,29), (3,22), (3,11)]