是否可以在Haskell中提供自定义模式分解?

时间:2013-12-21 12:47:20

标签: scala haskell pattern-matching type-constructor

在Haskell中,我有一个部分订单类型的模块:

data PartialOrder a = PartialOrder [a] [(a, a)]

我不导出值构造函数,因为这不是我想要使用的类型,但我仍然希望能够在模块外部模式匹配PartialOrder类型;这可能吗?特别是,我希望能够模式匹配不是类型构造函数的东西,而是模式匹配如下所示:

f (PartialOrder xs le) = ...

其中le是隐式定义值构造函数中定义的显式排序的函数。我知道Scala中有这样的工具,有没有办法在Haskell中做同样的事情?

提前致谢。

2 个答案:

答案 0 :(得分:12)

这听起来像ViewPatterns的用例。您可以编写类似的类型:

data ViewPartialOrder a = ViewPartialOrder a (a -> a -> Ordering)

编写如下函数:

viewOrder :: PartialOrder -> ViewPartialOrder
viewOrder (PartialOrder xs relation) = ...

然后使用ViewPatterns扩展名编写如下代码:

f (viewOrder -> ViewPartialOrder xs le) = ...

当然,你应该为这些事情提出更好的名字:P!

无论是好是坏,都无法使用隐式(即没有viewOrder函数)具有相同的效果。我认为这通常是一件好事,明确表示你不符合该类型的实际实现。

答案 1 :(得分:3)

使用视图模式的建议是很好的,但是通过预先组合“视图”(毕竟只是一个函数),你可以在没有视图模式的情况下获得相同的效果。

所以给出

viewOfPartialOrder :: PartialOrder -> ViewPartialOrder
viewOfPartialOrder (PartialOrder xs relation) = ...

由Tikhon Jelvis建议(名称略有不同),而不是

doSomethingWithAPartialOrder :: PartialOrder a -> Whatever
doSomethingWithAPartialOrder (viewOfPartialOrder -> ViewPartialOrder xs le) = ...

您可以定义

doSomethingWithAView :: ViewPartialOrder a -> Whatever
doSomethingWithAView (ViewPartialOrder xs le) = ...

doSomethingWithAPartialOrder :: PartialOrder a -> Whatever
doSomethingWithAPartialOrder = doSomethingWithAView . viewOfPartialOrder

我个人觉得用后一种方式编辑代码更容易,但你应该选择你个人喜欢的代码。