根据类型为泛型函数提供不同的函数体
假设我有一些泛型函数,
genericFunc :: a -> b
genericFunc x = doSomeHardWork
但对于特定类型,有一种更有效的方法可以完成genericFunc。
genericFunc :: ParticularType -> b
genericFunc x = doSomeEasyWork
将这两个函数体组合到同一个 genericFunc
中的最佳方法是什么,这样当在 PspecialType
上使用时,它将 doSomeEasyWork
,但是当用在其他类型上,它会doSomeHardWork
吗?我特别排除使用不同名称或不同模块的选项。
我相信这可以通过类型类来完成,但我对使用语言编译指示的解决方案更感兴趣。我有一种模糊的感觉,这可以通过语言实用来完成,但我不知道如何做。如果您比较和对比这些方法和/或任何其他可能的方法,则会获得加分。
Suppose I have some generic function
genericFunc :: a -> b
genericFunc x = doSomeHardWork
But for a particular type, there is a much more efficient way that genericFunc
could be done.
genericFunc :: ParticularType -> b
genericFunc x = doSomeEasyWork
What is the best way to combine these two function bodies into the same genericFunc
, such that when used on ParticularType
, it will doSomeEasyWork
, but when used on other types, it will doSomeHardWork
? I'm specifically excluding the option of using a different name, or different modules.
I believe this can be done with a typeclass, but I am more interested in solutions that use language pragmas. I have a vague inkling that this can be done with language pragmas but I have no idea how. Bonus points if you compare and contrast these approaches, and/or any other possible approaches.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

这可以通过在类定义中定义通用方法并在实例中覆盖它来使用类型类来完成。被覆盖的函数将始终被使用。
GHC 支持的另一种方法是使用重写规则。重写规则告诉 GHC 只要有可能就用另一个表达式替换一个表达式。如果替换的类型错误,则不会完成,因此您可以使用它来用专门的版本替换函数。重写规则由
{-# RULES #-}
编译指示给出。重写规则由编译器自行决定执行,因此在任何给定情况下可能会或可能不会调用专用函数。例如,重写可能取决于编译器是否决定内联函数:
This can be done with type classes by defining the general-purpose method in the class definition and overriding it in an instance. The overridden function will always be used.
An alternative supported by GHC is to use a rewrite rule. The rewrite rule tells GHC to replace one expression by another whenever possible. If the replacement is ill-typed, it will not be done, so you can use this to replace a function by a specialized version. The rewrite rule is given by a
{-# RULES #-}
pragma.Rewrite rules are performed at the discretion of the compiler, so the specialized function may or may not be called in any given situation. For example, the rewrite may depend on whether the compiler decides to inline a function: