String Haskell-基于某些条件的筛选字符串列表

String Haskell-基于某些条件的筛选字符串列表,string,list,haskell,filter,String,List,Haskell,Filter,我是这个社区的新手。我学习Haskell,在Haskell编码方面有困难。 我希望你能帮助我 我在这里和谷歌搜索,没有任何成功 我的问题是: 我想写一个函数,它以列表作为参数,如下所示: myStringListFilter :: [String] -> [String] not . (`elem` notAllowedChars) . head . tail myfunc xs = head xs 处理以下步骤: 删除第一个字母 myStringListFilter myList

我是这个社区的新手。我学习Haskell,在Haskell编码方面有困难。 我希望你能帮助我

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

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

myStringListFilter :: [String] -> [String]
not . (`elem` notAllowedChars) . head . tail
myfunc xs = head xs
处理以下步骤:

  • 删除第一个字母

    myStringListFilter myList = map tail strListe myList
    
  • 筛选列表中以“u”或“u”开头的每个元素

  • 第二步不行。我犯了一个错误

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

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

    过滤器的类型为

    filter :: (a -> Bool) -> [a] -> [a]
    
    因此,如果您想根据谓词筛选
    字符串的列表,您需要一个函数
    String->Bool
    ,但是您编写的,
    (`elem`['u',u'])
    具有类型
    Char->Bool

    所以你需要一个函数

    beginsWithU :: String -> Bool
    
    定义它最简单的方法是

    beginsWithU (c:_) = c == 'u' || c == 'U'
    beginsWithU _ = False                      -- empty list
    
    然后您误解了
    过滤器的工作原理,它保持满足谓词的元素,您希望删除它们,因此您需要使用
    not
    组合谓词(或者直接定义为
    not beginwithu

    但是,由于您实际上不想更改要保留在原始列表中的元素,那么

    myStringListFilter myList = filter (not . beginsWithU) (map tail myList)
    
    或者,无点:

    myStringListFilter = filter (not . beginsWithU) . map tail
    
    filterBy :: String -> String -> Bool
    filterBy notAllowedChars = 
        not . (`elem` notAllowedChars) . head . tail 
    
    将实现。因此,您也需要将
    尾部
    合并到谓词中,并且不需要
    映射
    ,这将产生

    myStringListFilter = filter (not . beginsWithU . tail)
    
    或者,如果输入列表中出现空
    字符串
    的可能性,则应妥善处理

    myStringListFilter = filter (not . beginsWith . drop 1)
    
    因为
    tail”“
    会产生
    ***异常:Prelude.tail:空列表
    ,而
    drop 1”“
    会产生

    但是,由于要保留原始列表元素,还可以定义谓词直接查看第二个字符

    secondCharIsU :: String -> Bool
    secondCharIsU (_:c:_) = c == 'u' || c == 'U'
    secondCharIsU _       = False
    
    myStringListFilter = filter (not . secondCharIsU)
    
    拟议的解决办法:

    beginsWithU (c:_) = c == 'u' || c == 'U'
    beginsWithU _ = False      
    
    myStringListFilter myList = filter (not . beginsWithU) (map tail myList)
    
    
    ghci>myStringListFilter ["butter", "cheese", "aUbergine", "egg", "milk", "bUbble", "curry"] 
    ["heese","gg","ilk"]
    
    …无法产生正确的输出

    映射更改原始字符串,因此过滤映射字符串列表不会生成包含任何原始字符串的列表。op需要使用自定义筛选器筛选原始列表:

    myFilter :: String -> String -> Bool
    myFilter notAllowedChars str = 
        if head (tail str)  `elem` notAllowedChars
        then False    --if match, reject this string
        else True     --if no match, include this string in result list 
    
    
    ghci>filter (myFilter "uU") ["butter", "cheese", "aUbergine", "egg", "milk", "bUbble", "curry"] 
    ["cheese","egg","milk"]
    
    无积分:

    myStringListFilter = filter (not . beginsWithU) . map tail
    
    filterBy :: String -> String -> Bool
    filterBy notAllowedChars = 
        not . (`elem` notAllowedChars) . head . tail 
    

    请记住,字符数组,例如['u','u'],与字符串“uU”是同一回事。

    我也是初学者,因此我的解释可能会有所帮助

    “点”是什么意思?它叫什么?例如,在这一行:

    过滤不允许的字符=不允许。(
    elem
    notAllowedChars)。头。尾巴

    dot表示“功能合成”,其中:

    定义为:

    f1 (f2 xs) 
    
    这意味着haskell取点f2右侧的函数,并对其应用xs:

    (f2 xs)
    
    然后haskell获取f2的返回值并将其应用于f1:

    f1 retValFromf2
    
    下面是一个使用函数组合的简单示例:

    func1 x = x * 2
    func2 x = x + 10
    
    dostuff x = (func1 . func2) x
    
    ghci> dostuff 0
    20
    
    myfunc xs = (tail . head) xs
    
    这里的过滤器是如何工作的?我在这行中没有看到任何过滤函数:

    过滤不允许的字符=不允许。(
    elem
    notAllowedChars)。头。尾巴

    该函数创建一个过滤器。该函数替代了我首先提供的非点自由函数:

    myFilter :: String -> String -> Bool
    myFilter notAllowedChars str = 
        if head (tail str)  `elem` notAllowedChars
        then False    --if match, reject this string
        else True     --if no match, include this string in result list
    
    因此,我应该更好地命名无点函数:

    createFilter notAllowedChars = not . (`elem` notAllowedChars) . head . tail
    
    您在右侧看到的是一系列函数组合,最右侧的函数tail首先执行。tail将列表作为参数并返回一个列表。然后将返回的列表应用于head。head将列表作为参数,并返回列表中的单个元素。部分功能:

    (`elem` notAllowedChars) 
    
    将左侧的一个elment作为参数,这正是head返回的值,而elem返回Bool。not将布尔值作为参数,例如True,并返回布尔值,例如False。请注意,当将函数与点链接在一起时,必须确保点右侧的函数返回的任何内容都是点左侧的函数接受的参数

  • 什么是真正的“无积分”
  • 我认为这意味着函数定义中没有指定参数。我喜欢将其视为xs是一个点列表,当xs术语没有出现在函数定义中的任何地方时,那么您就以无点风格编写了函数。圆点不是 “一点”。如果圆点是“一个点”,那么如下所示:

    myStringListFilter :: [String] -> [String]
    
    not . (`elem` notAllowedChars) . head . tail
    
    myfunc xs = head xs
    
    …很难被称为“无积分”

    在Haskell中,如果有这样定义的函数:

    myStringListFilter :: [String] -> [String]
    
    not . (`elem` notAllowedChars) . head . tail
    
    myfunc xs = head xs
    
    当x出现在等号两边的右边时,就像一个等式,你可以将它们抵消掉:

    myfunc = head
    
    如果你打电话:

    myfunc xs
    
    您将获得与原始myfunc定义相同的结果

    现在看看这个函数定义:

    myfunc xs = tail (head xs)
    
    在这种情况下,如果从两侧移除xs,则会得到:

    myfunc = tail (head)
    
    但tail将列表作为参数,而不是函数,因此会产生错误。但是,如果使用函数组合重写myfunc的右侧:

    func1 x = x * 2
    func2 x = x + 10
    
    dostuff x = (func1 . func2) x
    
    ghci> dostuff 0
    20
    
    myfunc xs = (tail . head) xs
    
    …然后您可以再次从两侧取消xs:

    myfunc = tail . head
    
    这又是一种无点风格。至于你为什么要费心用无点风格重写函数,我不确定。现在,我认为这是我能做到的。你会发现,当你学习一门计算机编程语言时,你会学到很多技巧。有时,当你学习一个技巧时,你不知道为什么它是有用的。你只需要接受这样一个事实,作为一个初学者,你并不总是能够理解为什么技巧是有用的。直到你变得更有经验,某个技巧的用处才变得明显

    在任何情况下,以无点风格编写函数都不会改变函数的工作方式,因此,如果您不理解它,请不要担心。随着你对哈斯克尔学习的深入,你可以做一些更高级的事情

    我的意图是理解哈斯克尔

    你应该意识到1)在我看来,Haskell是一门非常难学的语言,2)你可以