Haskell记录模式匹配

51

我正在寻找一种简化函数模式的方法,当实际数据不需要时:

data X = A | B String | C Int Int String
myfn :: X -> Int
myfn A = 50
myfn (B _) = 200
myfn (C _ _ _) = 500

有没有一种更简单的匹配模式来匹配C,只需丢弃值?

hsdev添加了一个提示“提示:使用记录模式”,但Google没有帮助我。

1个回答

103
您可以像这样使用记录模式:
data X = A | B {name :: String} | C {x::Int, y::Int, name::String}

myfn :: X -> Int
myfn A = 50
myfn B{} = 200
myfn C{} = 500

记录模式允许您给构造函数的字段命名。

您还可以执行以下操作:

myfn C{name=n} = length n

因此,您可以看到只能在需要的特定字段上进行模式匹配。

注意: 即使对于不使用记录语法的数据类型,您也可以使用记录模式:

data A = A Int | B Int Int

myfn A{} = 1
myfn B{} = 2

这很好。

  • RecordWildCards 允许您编写类似 C{..} 的内容,它等同于模式:C{x=x, y=y, name=name},即匹配所有字段后,你现在可以在作用域内找到匹配 x 字段值的变量 x 等等。

  • NamedFieldPuns 允许您编写 C{name} 以等效于 C{name=name},因此现在 name 在作用域内,并包含匹配 name 字段的值。

请记住,使用记录模式并不妨碍您按位置使用构造函数,因此您仍然可以编写:

myfn (B _) = 200

它只是 增加 功能。


太好了,谢谢。我实际上尝试了C{_}和C{..},但都没有成功。只是多了一个字符而已。^^ - theduke
9
很遗憾 Google 并没有帮助你很多关于 "haskell record pattern" 的问题。我已经重命名了这个问题,也许这样对他人更容易发现。 - theduke
1
@theduke:还要注意,即使您将B声明为普通的非记录数据类型,您仍可以使用空记录模式(B{})。 - Lii
@Lii 那是我没有考虑到的事情。我会在回答中提及它。 - Bakuriu
@Lili 谢谢你指出来。对我来说,从答案中显然就可以看出来了。 - theduke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接