wrl*_*wrl 10 haskell pattern-synonyms
考虑以下数据类型和模式同义词:
{-# LANGUAGE PatternSynonyms, NamedFieldPuns #-}
data Foo = Foo {
a :: Int
, b :: String
, c :: Maybe Bool
}
pattern Bar a b <- Foo { a, b }
pattern Baz c <- Foo { c }
Run Code Online (Sandbox Code Playgroud)
我想匹配Foo,但得到所有的a,b和c.像这样的东西(无效的Haskell):
showit :: Foo -> String
showit (Bar a b & Baz c) = show a ++ b ++ show c
Run Code Online (Sandbox Code Playgroud)
一种选择是使用ViewPattern:
dup :: a -> (a, a)
dup a = (a, a)
showall' :: Foo -> String
showall' (dup -> (Bar a b, Baz c)) = show a ++ b ++ show c
Run Code Online (Sandbox Code Playgroud)
但这会导致非详尽的匹配警告.但我们知道Bar并且Baz无可辩驳,因此匹配每个也是无可辩驳的.
如果没有编译器警告,如何表达?
这样做的动机是对大数据类型的字段使用细粒度模式同义词,并允许调用者只提取与记录类似的所需字段NamedFieldPuns.模式同义词还不支持记录语法,但它正在起作用:https://ghc.haskell.org/trac/ghc/ticket/8582
在我的情况下,我不能从模块中公开构造函数,因为我使用的是"智能构造函数"模式,因此无法为调用者提供与记录模式匹配的好处NamedFieldPuns.
请参阅/sf/answers/1761322461/作为灵感.我想扩大这个问题的答案的想法,允许呼叫者随意提取ň的米领域,为一个相当大的米.
编辑:事实证明,有一个相当广泛的问题PatternSynonyms和详尽的检查:https://ghc.haskell.org/trac/ghc/ticket/10339
这似乎使模式同义词用作字段提取器非常不愉快编译启用警告.
不确定这是否有帮助,但我会尝试一下。这些解决方案中的任何一个都可以接受吗?
showit :: Foo -> String
showit x@(Bar a b) = show a ++ b ++ show (c x)
showit' :: Foo -> String
showit' x@(Bar a b) = show a ++ b ++ showthat x
where
showthat (Baz c) = show c
Run Code Online (Sandbox Code Playgroud)