功能名findIndex
type定义是(a -> Bool) -> [a] -> Maybe Int
函数 find 返回满足谓词的列表的第一个元素,如果没有这样的元素,则返回 Nothing。 findIndex 返回对应的索引。 findIndices 返回所有此类索引的列表。
例子:
Input: findIndex (>3) [0,2,4,6,8]
Output: Just 2
double1 :: [Int]
double1 = map f evenList
where f z = z^2
evenList :: [Int]
evenList = filter even [1..20]
还有另一种方式
evenm = map (^2) (filter even [1..20])
第二种更简洁方便.
所以map后面跟运算符号, filter后面跟限制要求和范围,或者filter 后面跟其他功能+范围
pyths :: Int -> [(Int, Int, Int)]
pyths n =
[(a,b,c)|a <- [1..n], b<- [1..n],c <- [1..n],a^2 +b^2 == c^2]
这种[]的基本模板是,首先把结果放在最前面比如这里的(a,b,c)然后用分割线隔开, 把每个成分的范围说明,最后才是三者之间的联系
findIndices :: (Num a, Enum a) => (t -> Bool) -> [t] -> [a]
findIndices _ [] = []
findIndices p xs = [ i | (x,i) <- zip xs [0..], p x]
--indice 和indices 本质上是一样的都能得出正确结果
indice :: (Num a1, Enum a1, Eq a2) => a2 -> [a2] -> [a1]
indice a xs = [i |(x,i) <- zip xs [0..], a == x]
indices :: Eq a => a -> [a] -> [Int]
indices x xs = [ n | (v, n) <- zip xs [0..], v == x ]
filter 和[]能够起到一样的作用
records = [(True,5), (False,7), (True,12), (True,8),(False,15), (True,4)]
choose2 :: [(Bool, Integer)]
choose2 =[(x,y) |(x,y) <- records, x==True &&y<10 ]
choose1 :: [(Bool, Integer)]
choose1 = filter (\ (p,n) -> p && n < 10) records
这里(p,n) -> p 就代表了p是True的情况,如果想要代表False那么只需要加一个not变成以下这样(p,n) -> not p
本质上其实就是在做map 和filter
nine :: [Int] -> [Int]
nine [] = []
nine (x:xs)
|x >= 9 =(x-9):nine (xs)
|otherwise = x:(nine xs)
double :: Num a => a -> a
double x = x*2
luhnDouble :: (Ord a, Num a) => a -> a
luhnDouble a
|double a < 9 = double a
|double a >=9 = (double a)-9
factorial :: Int -> Int
factorial 0 = 1
factorial n
| n > 0 = n * factorial (n-1)
| otherwise = error "Input must be positive"
fact n = product [1..n]
fact2 0 =1
fact2 n = n * (fact2(n-1))
nfact n = product [n..(-1)]
nfact2 n = n * (fact2(n+1))
当还没学print的适合error这样表示
euclid :: Int -> Int -> Int
euclid n1 n2
| n1 == n2 = n1
| n1 > n2 = euclid (n1-n2) n2
| otherwise = euclid n1 (n2-n1)
com :: Int -> Int -> Int
com m n =
let c = min m n
st = [ x | x <- [c,c-1 .. 1], m `mod` x == 0 && n `mod` x == 0]
in head st
let in 也可以实现找到最大共因数
gradeBands :: [(String, Int)] -> (Int,Int,Int,Int,Int,Int)
gradeBands marks
= (count filter1, count filter2, count filter3,
count filter4, count filter5, count filter6)
where
filter1 n = n < 30
filter2 n = n >= 30 && n < 40
filter3 n = n >= 40 && n < 50
filter4 n = n >= 50 && n < 60
filter5 n = n >= 60 && n < 70
filter6 n = n >= 70
count filter
= length [ name | (name,grade) <- marks, filter grade]
当filter的东西比较多时,这是一个很好的例子
zip1 :: [Int] -> String -> [(Int,String)]
zip1 m n = zip m (toChar n)
toChar :: String -> [String]
toChar s = map (\c -> [c]) s
zip' :: [a] -> [b] -> [(a,b)]
zip' [] _ = []
zip' _ [] = []
zip' (a:as) (b:bs) = (a,b) : zip' as bs
运行后得到的结果跟输入的结果完全一致
same xs = foldr (++) [] (map sing xs)
where
sing x = [x]
sortvalue整理任意两个通过其包含的大小,而sort 是整理整个list让它从小到大的排序
sortvalue :: (String, Int) -> (String, Int) -> Bool
sortvalue (_,g1) (_,g2) = g1 <= g2
sort :: [Int] -> [Int]
sort [] = []
sort [x] = [x]
sort (x:xs) = sort smaller ++ [x] ++ sort larger
where
smaller = filter (<= x) xs
larger = filter (> x) xs
maximum’是使用其中一种折叠函数实现最大的功能。
maximum’ xs = foldl (max) xs
max1 :: [Int] -> Int
max1 []= 0
max1 [x] = x
max1 (x:xs)
|(max1 xs) > x = max1 xs
|otherwise = x
map 和 filter 可以转换成 list comprehensions
总结以下: 通过map 里面的变化或者算法得到的结果放在list comprehension 的 | 前面,如果没有map 那么就默认只有x.
!!注意顺序map 和 filter 的前后不同,同一个公式的结果可能不同
(a) map (+3) xs
[x+3 | x <- xs]
(b) filter (>7) xs
[x | x <- xs, x>7]
(c) concat (map (\x -> map (\y -> (x,y)) ys) xs)
[(x,y) | x<-xs, y<-ys]
(d) filter (>3) (map (\(x,y) -> x+y) xys)
[ x+y | (x,y) <- xys, (x+y) > 3 ]
使用 foldr 重新定义地图 f 和过滤器 p
这个特别重要,一定要记住
map' f = foldr ((:).f) []
filter' p = foldr (\x xs -> if p x then x : xs else xs) []
--OR
filter'' p = foldr (\x -> if (p x) then (x:) else id) []