使用哈姆雷特的$ case与记录和ADT

时间:2012-11-06 14:14:36

标签: haskell yesod hamlet

看起来哈姆雷特的$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的构造函数(以后引用字段)?事实是我甚至想要做这种匹配我正在做错的标志吗?

1 个答案:

答案 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 '\'')

因此只接受一个或多个序列(后跟(标识符或通配符)的空格)。

你可以从这里扩展它。

干杯!