2012-09-06 90 views
2

haskell有可能匹配複雜模式嗎?複雜模式匹配

我的意思是,我有一個逗號分體值(CSV)文件:

name,ID,fieldA,fieldB 

是有可能寫出像一個函數:

getName (n:',':xs) = n 

其中n是不是一個單一的元素,但一清單?

+1

您可以使用[View Patterns](http://www.cs.cmu.edu/~drl/pubs/lpj07views/lpj07views-anglohaskell.pdf)根據另一個函數的輸出執行「匹配」。 –

回答

3

你應該寫一個函數來分割你的行......

import Data.List 

parts = map tail . groupBy (/=) . (',':) 

然後你就可以輕鬆編寫訪問函數:

getName xs = n where [n,_,_,_] = parts xs 
getID xs = i where [_,i,_,_] = parts xs 
... 

然而,總是這將是很好使用的數據類型:

data Record = Record {getName :: String 
        ,getId :: Int 
        ,getFieldA 
        ,getFieldB :: String 
        } deriving Show 

initRecord xs = Record name (read id) fieldA fieldB where 
       [name, id, fieldA, fieldB] = parts xs 

當然,如果你需要的錯誤處理,它會變得更加困難...

順便說一句,這裏有一個Haskell CSV庫:http://hackage.haskell.org/packages/archive/csv/0.1.1/doc/html/Text-CSV.html

+0

FYI,還有一個更新的CSV庫:http://hackage.haskell.org/package/cassava – jtobin

1

哼,我不確定,但我不這麼認爲。你應該在Haskell中檢查一下regular expressions以解決你的問題。

6

當我在20世紀80年代還是個小男孩的時候,我實現了一種功能性語言,它具有複雜的風格。它等於允許++模式。由此產生的模式不明確,所以匹配涉及回溯搜索過程:程序員可以有效地指定是否最小化或最大化匹配++左側模式的前綴長度。該語言有一種「模式守衛」的形式,以便可以測試候選匹配,以查看後續計算是否成功並在失敗的情況下被拒絕。由此產生的程序通常在他們的意義上顯而易見。這非常有趣。

這些天,當遇到這樣的問題時,我達到了span,如果這不會削減它,我使用解析器組合器。

span :: (a -> Bool) -> [a] -> ([a], [a]) 

跨度,施加到謂詞p和列表XS,返回一個元組,其中第一元件是最長滿足p和第二元件的元件的XS的前綴(可能爲空)是該列表的其餘部分

因此,特別span (/= ',')將拆分String到什麼是第一個逗號(或者如果沒有逗號整個事情),其餘的(用逗號開始,如果有)前。

如果這不會削減它,我使用分析器組合器。

但我總是記得它過去很容易。

+1

聽起來就像你在[本文](http://www.springerlink.com/content/y2k73226883h4l58)之前幾年發明了函數式邏輯編程語言Curry中的函數模式一樣的機制。功能模式的標準示例是last的以下定義。 '最後(xs ++ [x])= x' –

+0

或許。我還允許重複變量與平等測試,所以'elem x(_ ++ x:_)= True; elem _ _ = False'例如 – pigworker

2

您可以使用Data.List.Split之類的splitOn之類的東西,然後在列表元素上進行模式匹配。

> splitOn "," "a,b,c,d" 
["a","b","c","d"] 

它是在分割包。

對於更復雜的事情,您可以使用Parsec。