String Haskell-基于某些条件的筛选字符串列表
我是这个社区的新手。我学习Haskell,在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
myStringListFilter :: [String] -> [String]
not . (`elem` notAllowedChars) . head . tail
myfunc xs = head xs
处理以下步骤:
myStringListFilter myList = map tail strListe myList
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)你可以