首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在与ViewPatterns匹配之前先映射到PatternSynonyms参数?

在与ViewPatterns匹配之前先映射到PatternSynonyms参数?
EN

Stack Overflow用户
提问于 2017-09-21 21:16:37
回答 1查看 50关注 0票数 1

我最近正在尝试将ADT重构为向后兼容的集合表示:

代码语言:javascript
复制
data Tag = TagFoo | TagBar !Text | TagBaz !Int ... -- many more
           deriving (Eq, Generic, Ord, Show)

newtype Label = Label (HashSet Tag)
                deriving (Eq, Generic, Show)

为此,我定义了几个模式同义词,其效果如下:

代码语言:javascript
复制
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE ViewPatterns #-}

pattern Foo :: Label
pattern Foo <- Tags [TagFoo] where
  Foo = Label $ HashSet.singleton TagFoo

-- (let's say a lone TagBar is invalid)

pattern FooWithBar :: Text -> Label
pattern FooWithBar b <- Tags [TagFoo, TagBar b] where
   FooWithBar b = Label $ HashSet.fromList [TagFoo, TagBar b]

Tags模式定义为:

代码语言:javascript
复制
 pattern Tags :: [Tag] -> Label
 pattern Tags ts <- ((\(Label ts') -> sort $ HashSet.toList ts') -> ts)

不幸的是,这个表单很容易出错,因为它要求用户在正确的Order中提供[Tag]列表。否则,像Tags [TagBar "x", TagFoo]这样的模式将不会与Label $ HashSet.fromList [TagBar "x", TagFoo]匹配。(不做sort就更糟了,因为标签的顺序是任意的)。

理想情况下,Haskell (或无序容器?)将提供一种对HashSet的元素进行模式匹配的方法。但是另一种方法可以是通过HashSet.fromList映射Tags ts模式的ts参数,然后比较结果集:

代码语言:javascript
复制
pattern Tags ts <- ((\(Label ts') -> ts' == HashSet.fromList ts) -> True)

然而,这是不可能的,因为视图模式函数不能使用模式同义词的参数。但是尝试在view函数之外进行转换:

代码语言:javascript
复制
pattern Tags ts <- ((\(Label ts') -> ts') -> HashSet.fromList ts == ts')

这也是不可能的,因为->后面的部分是一个模式,不允许应用函数。

有没有其他方式定义允许这种匹配的模式同义词?

EN

回答 1

Stack Overflow用户

发布于 2017-09-21 21:43:00

Tags真的需要成为一种模式吗?简单地提供一个函数有什么错:

代码语言:javascript
复制
toLabel :: [Tags] -> Label

并让用户使用卫士:

代码语言:javascript
复制
someFunction lab | lab == toLabel [TagFoo, TagBar "bar"] = ...
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46344980

复制
相关文章

相似问题

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