考虑以下多行字符串S
:
apple
banana berry
cantelope
我正在尝试编写/定位Haskell函数,我将在此帖or-match
和and-match
中调用。以下是他们应该做的一些例子:
or-match S ("apple","berry")
{- should return the two line string:
apple
banana berry
-}
and-match S ("apple", "berry") --should return the empty string, or something like "No matches."
and-match S ("banana" "berry") --should return a single line containing "banana berry"
在上面的示例中,我使用(String, String)
类型作为or-match
和and-match
的域参数。我不确定这是最好的方法,因为我可能想要使用两个以上的参数。我是Haskell的新手,但我不确定如何将一个任意长度的元组作为函数的参数。
总之,这篇文章的整体问题:如何在Haskell中创建or-match
和and-match
,这样每个函数的域参数都是任意长度的元组(或允许任意长度搜索的某种类型)?
答案 0 :(得分:4)
你可以写
andMatchPred, orMatchPred :: Eq a => [a] -> [a] -> Bool
andMatchPred needles haystack = all (`elem` haystack) needles
orMatchPred needles haystack = any (`elem` haystack) needles
然后您想要的功能可以写成
andMatch, orMatch :: Eq a => [a] -> [[a]] -> [[a]]
andMatch = filter . andMatchPred
orMatch = filter . orMatchPred
如果事实证明这是一个瓶颈,那么应该有很多机会来提高效率,但应该首先考虑简单易读的实现。
快速使用ghci来展示如何使用它:
> let s = [["apple"],["banana","berry"],["cantelope"]]
> andMatch ["apple", "berry"] s
[]
> orMatch ["apple", "berry"] s
[["apple"],["banana","berry"]]
答案 1 :(得分:2)
这样每个函数的域参数是一个任意长度的元组(或某种允许任意长度搜索的类型)?
您正在寻找列表,特别是在这种情况下[String]
。元组是固定长度的,但在每个位置允许不同的类型,列表是同质的,意味着每个值必须具有相同的类型,但具有任意长度。
所以你要找的是
类型的函数orMatch, andMatch :: [String] -> [String] -> [String]
您需要一个您自己必须编写的函数hasSubString :: String -> String -> Bool
,但您的代码可能类似于以下伪代码:
orMatch lines searchTerms = filter (\line -> any (hasSubString line) searchTerms) lines
andMatch lines searchTerms = filter (\line -> all (hasSubString line) searchTerms) lines
其中
hasSubString string substring
如果True
中出现substring
,则会返回string
,否则会返回False
。例如hasSubString "hello, world" "world" == True
,hasSubString "hello, world" "unicorns" == False