假設我想爲匹配以字符'Z'開頭的字符串的函數做一個特殊情況。我可以很容易做到這一點通過執行類似下面的使用模式匹配:Haskell中的模式匹配字符串前綴
myfunc ('Z' : restOfString) = -- do something special
myfunc s = -- do the default case here
但是,如果我想有更長的前綴匹配字符串是什麼?假設我想爲以「烤麪包機」一詞開頭的字符串開一個特例。編寫匹配這樣的字符串的模式的最佳方法是什麼?
假設我想爲匹配以字符'Z'開頭的字符串的函數做一個特殊情況。我可以很容易做到這一點通過執行類似下面的使用模式匹配:Haskell中的模式匹配字符串前綴
myfunc ('Z' : restOfString) = -- do something special
myfunc s = -- do the default case here
但是,如果我想有更長的前綴匹配字符串是什麼?假設我想爲以「烤麪包機」一詞開頭的字符串開一個特例。編寫匹配這樣的字符串的模式的最佳方法是什麼?
myfunc ('t':'o':'a':'s':'t':'e':'r' : restOfString) = ...
使用正常模式匹配工作,但由於前綴字符串變長而變得麻煩。
{-# LANGUAGE PatternGuards #-}
import Data.List
myFunc string | Just restOfString <- stripPrefix "toaster" string =
-- do something special
myFunc string = -- do the default case here
使用庫函數而不是模式匹配可以更容易讀取和寫入。
{-# LANGUAGE ViewPatterns #-}
import Data.List
myFunc (stripPrefix "toaster" -> Just restOfString) = -- do something special
myFunc string = -- do the default case here
GHC 6.10語法擴展使得這種用法更加自然。
當然,後兩者是完全等價的,我們可以在沒有任何糖的情況下做(混亂地)。
import Data.List
myFunc string =
if restIsJust
then -- do something special
else -- do the default case here
where
(restIsJust, restOfString) =
case stripPrefix "toaster" string of
Just something -> (True, something)
Nothing -> (False, undefined)
雖然這些語法擴展是爲了讓我們的生活更輕鬆。
myfunc ('t' : 'o' : 'a' : 's' : 't' : 'e' : 'r' : restOfString)
據我所知,沒有比這更簡潔的語法。
您當然也可以檢查字符串是以guard-clause中的烤麪包機還是以函數體內的if
開頭。
import Data.List
myFunc str | "toaster" `isPrefixOf` str = something restOfString
| otherwise = somethingElse
where Just restOfString = stripPrefix "toaster" str
我在想第一個這樣的東西,但是必須兩次寫'烤麪包機'似乎很愚蠢。 – ephemient 2009-10-21 20:00:07
拆分庫http://hackage.haskell.org/packages/archive/split/0.1.1/doc/html/Data-List-Split.html有許多用字符串拆分字符串的功能,包括前綴匹配。你可能會發現一些有用的東西。
myFunc str =
case stripPrefix "toaster" str of
Just restOfString -> something restOfString
Nothing -> somethingElse
這就是爲什麼stripPrefix返回一個Maybe類型。
非常簡單,編寫並調用模板哈斯克爾來達到預期的效果。儘管如此,我還不足以確定一個TH人。 – 2009-10-22 06:55:38
不幸的是,GHC沒有實現模式拼接(據我所知,顯然它很難),所以這是不可能的。 – ephemient 2009-10-22 18:18:19