Haskell - 基于某些条件过滤字符串列表 [英] Haskell - filter string list based on some conditions

查看:168
本文介绍了Haskell - 基于某些条件过滤字符串列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在这个社交中是新的。我学习了Haskell,并且在Haskell编码上遇到困难。
我希望你能帮助我。



我在这里和谷歌搜索,没有任何成功。

我的问题是因为fowllows:
我想写一个函数,它需要一个列表作为参数,如下所示:

pre $ myStringListFilter :: [String] - >




$ b

处理步骤如下:删除第一个字母

  myStringListFilter myList =地图尾部strListe myList 


  • 过滤列表中以u或U开头的每个元素。


    $ b $

      myStringListFilter myList = filter('elem' ['u','U'])(map tail strListe myList)


  • 第二步不起作用。我得到错误。

    如果我想要以下内容,我该如何实现解决方案:

    $ pre> 输入:[butter,chees,aUbergine,egg,milk,bUbble,curry]

    输出:[chees ,egg,milk]


    解决方案

    类型过滤器

      filter ::(a  - > Bool ) - > [a]  - >所以如果你想筛选 String 的列表, code> s根据谓词,你需要一个函数 String  - > Bool ,但是你写的(`elem` ['u',U'])的类型是 Char  - > Bool 



    所以你需要一个函数

      startsWithU :: String  - > Bool 

    最简单的定义方式是

      startsWithU(c:_)= c =='u'|| c =='U'
    startsWithU _ = False - 空列表

    误解了过滤器是如何工作的,它保留了满足谓词的元素,你想删除它们,所以你需要用不是(或者直接定义为不能直接用$ / code>)。

    但是,如 7stud 指出,你实际上并不想改变你想从原始列表中保留的元素,什么

      myStringListFilter myList = filter(not。startsWithU)(map tail myList)

    或者无点:

      myStringListFilter = filter(not。beginsWithU)。地图尾巴

    会实现。所以你需要将 tail 并入到谓词中,并且不需要 map ,这会产生

      myStringListFilter = filter(not。startsWithU。tail)

    ,或者如果在输入列表中出现空的 String 的可能性应该得到良性处理,

      myStringListFilter = filter(not。startsWith。drop 1)

    由于 tail会产生一个 ***异常:Prelude.tail:空列表 drop 1产生



    但是,如果您想保留原始列表元素,您还可以定义谓词来直接查看第二个字符,

      secondCharIsU :: String  - > Bool 
    secondCharIsU(_:c:_)= c =='u'|| c =='U'
    secondCharIsU _ = False

    myStringListFilter = filter(not。secondCharIsU)


    I am new in this comunity. I learn Haskell and have difficulties with Haskell-coding. I hope you can help me.

    I searched here and in Google, without any success.

    My problem ist as fowllows: I want to write a function which takes a list as parameter like this:

    myStringListFilter :: [String] -> [String]
    

    process the following steps:

    1. Remove the first letter

      myStringListFilter myList = map tail strListe myList
      

    2. Filter every element in the list which begins with "u" or "U".

      myStringListFilter myList = filter (´elem´ ['u', 'U']) (map tail strListe myList)
      

    Step two doesn't work. I get error.

    How do I achieve the solution, if I want the following:

    Input: ["butter", "chees", "aUbergine", "egg", "milk", "bUbble", "curry"]
    
    Output: ["chees", "egg", "milk"]
    

    解决方案

    The type of filter is

    filter :: (a -> Bool) -> [a] -> [a]
    

    so if you want to filter a list of Strings according to a predicate, you need a function String -> Bool, but what you wrote, (`elem` ['u',U']) has type Char -> Bool.

    So you need a function

    beginsWithU :: String -> Bool
    

    the easiest way to define it is

    beginsWithU (c:_) = c == 'u' || c == 'U'
    beginsWithU _ = False                      -- empty list
    

    Then you have misunderstood how filter works, it keeps the elements satisfying the predicate, you want to remove them, so you need to compose the predicate with a not (or define as doesn'tbeginWithU directly).

    However, as 7stud points out, you do not actually want to change the elements you want to keep from the original list, what

    myStringListFilter myList = filter (not . beginsWithU) (map tail myList)
    

    or, point-free:

    myStringListFilter = filter (not . beginsWithU) . map tail
    

    would achieve. So you need to incorporate the tail into the predicate too, and need no map, that would yield

    myStringListFilter = filter (not . beginsWithU . tail)
    

    or, if the possibility that an empty String occurs in the input list shall be dealt with benignly,

    myStringListFilter = filter (not . beginsWith . drop 1)
    

    since tail "" would produce an *** Exception: Prelude.tail: empty list whereas drop 1 "" produces "".

    But, as you want to keep the original list element, you can also define the predicate to directly look at the second character,

    secondCharIsU :: String -> Bool
    secondCharIsU (_:c:_) = c == 'u' || c == 'U'
    secondCharIsU _       = False
    
    myStringListFilter = filter (not . secondCharIsU)
    

    这篇关于Haskell - 基于某些条件过滤字符串列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆