在haskell中有可能匹配复杂的模式吗?
我的意思是,我有一个逗号分隔值(CSV)文件:
name,ID,fieldA,fieldB是否可以编写如下函数:
getName (n:',':xs) = n其中n不是单个元素而是一个列表?
发布于 2012-09-06 18:38:29
你应该写一个函数来拆分你的行...
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
发布于 2012-09-06 18:16:02
当我在20世纪80年代还是个小男孩的时候,我用那种风格实现了一种具有复杂模式的函数式语言。它相当于允许在模式中使用++。生成的模式是不明确的,因此匹配涉及回溯搜索过程:程序员可以有效地指定是最小化还是最大化与++左模式匹配的前缀的长度。该语言具有“模式保护”的形式,因此可以测试候选匹配,以查看后续计算是否成功,以及在失败的情况下是否被拒绝。由此产生的程序通常是显而易见的,因为它们的含义。这真的很有趣。
如今,当遇到这样的问题时,我会求助于span,如果这还不能解决问题,我就使用解析器组合子。
span :: (a -> Bool) -> [a] -> ([a], [a])跨度,应用于谓词p和列表xs,返回一个元组,其中第一个元素是满足p的元素的xs的最长前缀(可能为空),第二个元素是列表的剩余部分
因此,特别是span (/= ',')会将String拆分成第一个逗号之前的所有内容(如果没有逗号,则将整个内容拆分),其余部分(如果有逗号,则从逗号开始)。
如果这还不能解决问题,我会使用解析器组合子。
但我一直记得它曾经是多么的简单。
发布于 2012-09-06 18:37:40
您可以使用Data.List.Split中的splitOn之类的内容,然后对列表元素进行模式匹配。
> splitOn "," "a,b,c,d"
["a","b","c","d"]它在拆分包中。
对于更复杂的情况,可以使用Parsec。
https://stackoverflow.com/questions/12297532
复制相似问题