2

看起来哈姆雷特的$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 的构造函数匹配的推荐方法是什么(稍后参考字段)?我什至想做这种匹配的事实是否表明我做错了(TM)?

4

1 回答 1

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

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

你可以从这里扩展它。

干杯!

于 2012-11-06T16:11:06.597 回答