2016-04-28 70 views
0

考慮以下多行字符串S如何在Haskell中創建這些字符串匹配函數?

apple 
banana berry 
cantelope 

我想寫/定位Haskell函數,我將在這篇文章or-matchand-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-matchand-match域參數。我不確定這是最好的方式,但我可能想使用兩個以上的參數。雖然我是Haskell的新手,但我不確定如何使任意長度的元組成爲函數的參數。

總之,這篇文章的整體問題:我如何or-match和哈斯克爾and-match,使得對於每這些功能域參數是任意長度的元組(或某些類型的,允許任意一個搜索長度)?

回答

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"]] 
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出現在stringFalse中。例如hasSubString "hello, world" "world" == True,hasSubString "hello, world" "unicorns" == False

+0

沒有必要自己實現'hasSubString';標準庫將其作爲'isInfixOf',並且Hackage上存在更高效的版本。 –

相關問題