在Haskell中,我有一个部分订单类型的模块:
data PartialOrder a = PartialOrder [a] [(a, a)]
我不导出值构造函数,因为这不是我想要使用的类型,但我仍然希望能够在模块外部模式匹配PartialOrder类型;这可能吗?特别是,我希望能够模式匹配不是类型构造函数的东西,而是模式匹配如下所示:
f (PartialOrder xs le) = ...
其中le
是隐式定义值构造函数中定义的显式排序的函数。我知道Scala中有这样的工具,有没有办法在Haskell中做同样的事情?
提前致谢。
答案 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
我个人觉得用后一种方式编辑代码更容易,但你应该选择你个人喜欢的代码。