我需要编写一个函数,通过使用列表解析来检查一个子字符串是否在另一个字符串中。
我使用drop
从一个字符串创建一个字符串列表,使用isPrefixOf
将创建的字符串列表与子字符串进行比较。
下面是我的代码:
contains :: String -> String -> Bool
contains str substr = isPrefixOf substr (check str)
where
check :: String -> [String]
check str
|str==[] = []
|otherwise = [drop x str | x <- [0..length(str)-1]]
然而,我得到这个错误:
Tutorial2.hs:163:42: error:
* Couldn't match type `[Char]' with `Char'
Expected type: [Char]
Actual type: [String]
* In the second argument of `isPrefixOf', namely `(check str)'
In the expression: isPrefixOf substr (check str)
In an equation for `contains':
contains str substr
= isPrefixOf substr (check str)
where
check :: String -> [String]
check str
| str == [] = []
| otherwise = [drop x str | x <- [0 .. length (str) - 1]]
|
163 | contains str substr = isPrefixOf substr (check str)
我想知道为什么我会得到这个错误,我该如何修复它。我假设这是因为我给isPrefixOf一个list a的列表,它不接受这个函数check string。
3条答案
按热度按时间rekjcdws1#
**
IsPrefixOf :: Eq a => [a] -> [a] -> Bool
**需要两个相同类型的列表(并且该类型应该是Eq
类型类的成员),因此例如两个String
,因为String
是Char
的列表。然而,您提供了一个
String
(substr
)和一个String
列表(check str
的类型为[String]
)。因此,这将不会进行类型检查。此外,多次使用drop
将使check str
在 O(n2) 中运行,这是低效的。你可以使用**
any :: Foldable f => (a -> Bool) -> f a -> Bool
来检查 predicate 是否满足可折叠列表中的任何元素,例如一个列表。我们还可以使用tails :: [a] -> [[a]]
**来以更有效的方式获得列表的所有尾部(包括完整列表):我们可以进一步将其推广为与作为
Eq
类型类的成员的任何类型a
的列表一起工作:我们还可以通过使用**
flip :: (a -> b -> c) -> b -> a -> c
和(.) :: (b -> c) -> (a -> b) -> a -> c
**使函数 * 无点 *:i7uaboj42#
问题是
isPrefixOf
需要一个String
,但您的check
返回一个字符串列表([String]
)。修复方法是将
isPrefixOf
Package 在any
中,这样就可以将函数Map到整个列表:请注意,
check
等价于内置的tails
(从技术上讲,它应该是length str
,而不是length str - 1
,但在本例中这并不重要),所以如果我们进行替换,我们将得到Willem's solution:vxf3dgd43#
有一种更简单的方法(与目前为止发布的答案相比)来检查一个字符串是否是另一个字符串的子字符串。可以使用Data.List中的isInfixOf函数。
下面是签名:
第一个参数是子字符串,第二个参数是要在其中检查子字符串的更大字符串。
以下是文档:)