Haskell:自动创建constuctor-checker / selector函数

时间:2016-02-07 11:34:43

标签: haskell

在haskell中,ADT有一个常见的习惯用法,例如:

data MyData a = X a | Y a | Z a

...定义函数:

isX (X _) = True
isX _     = False

isY (Y _) = True
isY _     = False

isZ (Z _) = True
isZ _     = False

有没有办法自动生成这些功能?

动机:这可以说是惯用的,或者不是惯用的haskell,取决于你问的人......标准库本身有isJustisNothing

扩展问题的范围,记录语法允许您为数据类型创建函数:

data MyData = A { a1 :: Type1, a2 :: Type2 } | B { b1 :: Type3, b2 :: Type4 }

这些功能有以下类型:

a1 :: MyData -> Type1
a2 :: MyData -> Type2
b1 :: MyData -> Type3
b2 :: MyData -> Type4

虽然这对于只有1个构造函数的数据类型来说无疑是很好的,但对于具有多于1个构造函数的数据类型来说则更少,因为当使用了错误的构造函数时,自动生成的函数会导致错误。

有没有办法自动生成这些类型的函数?

a1 :: MyData -> Maybe Type1
a2 :: MyData -> Maybe Type2
b1 :: MyData -> Maybe Type3
b2 :: MyData -> Maybe Type4

1 个答案:

答案 0 :(得分:4)

这种模式是个坏主意。它会导致容易出错的代码。但是,有一种更好的方法,也包括这种机制,并积极回答你的问题。使用Prisms。您可以使用Template Haskell automatically derive使用它们。然后你可以使用is来获得你想要的东西,但是,你仍然不应该在正常情况下。尽管如此,通过提供棱镜,您的用户可以使用更好的方法,同时在更方便时仍可访问is

最终结果是像

这样的代码
data MyData a = X a | Y a | Z a
makePrisms ''MyData

filterX = filter (is _X)