• Haskell使用了map/filter和zip来实现功能的例子


    Haskell中map/filter/zip以及fodlr来实现功能的例子

    功能名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])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    第二种更简洁方便.
    所以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]
    
    • 1
    • 2
    • 3

    这种[]的基本模板是,首先把结果放在最前面比如这里的(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 ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    这里(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
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    
    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))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    当还没学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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    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]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    当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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    运行后得到的结果跟输入的结果完全一致

    same xs = foldr (++) [] (map sing xs)
                where
                sing x = [x]
    
    • 1
    • 2
    • 3

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    maximum’是使用其中一种折叠函数实现最大的功能。

    maximum’ xs = foldl (max) xs
    
    max1 :: [Int] -> Int
    max1 []= 0
    max1 [x] = x
    max1 (x:xs) 
        |(max1 xs) > x = max1 xs
        |otherwise = x
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    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 ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    使用 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) []
    
    • 1
    • 2
    • 3
    • 4
  • 相关阅读:
    ChatGPT 1.0.0安卓分析,仅限国内分享
    谷歌翻译器-在线实时批量谷歌翻译器
    数据结构--二叉树
    提升Mac运行速度的十大小技巧,你用过几个?
    pandas教程:Periods and Period Arithmetic 周期和周期运算
    暗影骑士擎Pro 之 安装Ubuntu18.04 双系统 踩坑记录(一)
    Redis 连接不上 WRONGPASS invalid username-password pair
    arduino压力传感器
    【实战】Kubernetes安装持久化工具NFS-StorageClass
    基于神经网络的智能系统,神经元网络控制的作用
  • 原文地址:https://blog.csdn.net/kirsten111111/article/details/126411690