看起来哈姆雷特的$case
表达式应该非常有用,但我无法弄清楚如何匹配具有多个构造函数的记录类型,这些构造函数缺少模式匹配(具有唯一名称)领域。假设我有数据类型,
data A = A1 { v1,v2,v3 :: Int }
| A2 { g :: Double}
在我的模板中,我希望以A1
值的方式呈现A2
值。人们会认为我可以做到,
$case myA
$of a@(A1 {})
<p>This is an A1: #{show $ v1 a}
$of a@(A2 {})
<p>This is an A2: #{show $ g a}
不幸的是,此代码段无法使用语法错误进行编译,这表明不支持@
语法。如果我删除a@
,我会收到另一个语法错误,这次建议也不支持记录括号表示法。
最后,在绝望中,一旦可以尝试,
$case myA
$of A1 _ _ _
...
但是,唉,即使这不编译(_的冲突定义)。因此,似乎唯一的选择是,
$case myA
$of A1 v1 v2 v3
...
这种基于订单的模式匹配对于大型数据类型非常烦人,特别是当一个人被迫命名每个字段时。
那么,我在这里错过了什么?哈姆雷特的案例分析真的有限吗?建议的方法是匹配ADT的构造函数(以后引用字段)?事实是我甚至想要做这种匹配我正在做错的标志吗?
答案 0 :(得分:2)
您可以跟踪小村处理。
答案在非暴露模块Text.Hamlet.Parse中
controlOf = do
_ <- try $ string "$of"
pat <- many1 $ try $ spaces >> ident
_ <- spaceTabs
eol
return $ LineOf pat
where
ident = Ident <$> many1 (alphaNum <|> char '_' <|> char '\'')
因此只接受一个或多个序列(后跟(标识符或通配符)的空格)。
你可以从这里扩展它。
干杯!