首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >复杂模式匹配

复杂模式匹配
EN

Stack Overflow用户
提问于 2012-09-06 18:00:37
回答 4查看 410关注 0票数 2

在haskell中有可能匹配复杂的模式吗?

我的意思是,我有一个逗号分隔值(CSV)文件:

代码语言:javascript
运行
复制
name,ID,fieldA,fieldB

是否可以编写如下函数:

代码语言:javascript
运行
复制
getName (n:',':xs) = n

其中n不是单个元素而是一个列表?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-09-06 18:38:29

你应该写一个函数来拆分你的行...

代码语言:javascript
运行
复制
import Data.List

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

然后,您可以轻松地编写访问器函数:

代码语言:javascript
运行
复制
getName xs = n where [n,_,_,_] = parts xs
getID   xs = i where [_,i,_,_] = parts xs
...

但是像往常一样,使用数据类型会更好:

代码语言:javascript
运行
复制
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

票数 3
EN

Stack Overflow用户

发布于 2012-09-06 18:16:02

当我在20世纪80年代还是个小男孩的时候,我用那种风格实现了一种具有复杂模式的函数式语言。它相当于允许在模式中使用++。生成的模式是不明确的,因此匹配涉及回溯搜索过程:程序员可以有效地指定是最小化还是最大化与++左模式匹配的前缀的长度。该语言具有“模式保护”的形式,因此可以测试候选匹配,以查看后续计算是否成功,以及在失败的情况下是否被拒绝。由此产生的程序通常是显而易见的,因为它们的含义。这真的很有趣。

如今,当遇到这样的问题时,我会求助于span,如果这还不能解决问题,我就使用解析器组合子。

代码语言:javascript
运行
复制
span :: (a -> Bool) -> [a] -> ([a], [a])

跨度,应用于谓词p和列表xs,返回一个元组,其中第一个元素是满足p的元素的xs的最长前缀(可能为空),第二个元素是列表的剩余部分

因此,特别是span (/= ',')会将String拆分成第一个逗号之前的所有内容(如果没有逗号,则将整个内容拆分),其余部分(如果有逗号,则从逗号开始)。

如果这还不能解决问题,我会使用解析器组合子。

但我一直记得它曾经是多么的简单。

票数 6
EN

Stack Overflow用户

发布于 2012-09-06 18:37:40

您可以使用Data.List.Split中的splitOn之类的内容,然后对列表元素进行模式匹配。

代码语言:javascript
运行
复制
> splitOn "," "a,b,c,d"
["a","b","c","d"]

它在拆分包中。

对于更复杂的情况,可以使用Parsec。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12297532

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档