Zhi*_*gor 1 haskell types functional-programming
我想要一个函数f作为Ints的增量和所有其他类型的标识。我尝试启用TypeApplications扩展并以最直接的方式执行此操作:
f :: forall a. a -> a
f @Int x = x + 1
f @_ x = x
Run Code Online (Sandbox Code Playgroud)
但是扩展并没有启用这样的模式:
<interactive>:6:1: error: Parse error in pattern: f @Int
Run Code Online (Sandbox Code Playgroud)
Haskell 中是否有类型(或类似机制)的模式匹配?
如前所述,这在 Haskell 中是不可能实现的,因为它会违反称为“参数性”的参数多态性的基本属性之一,它确保任何多态函数满足称为“自由定理”的特定属性。
特别是,类型的终止函数forall a. a -> a必须是身份。没有其他可能的实现。
话虽如此,如果我们允许对 type 进行约束a,这将成为可能。通常,运行时类型测试是通过Typeable类型类在 Haskell 中完成的:
f :: forall a. Typeable a => a -> a
f x = case eqT @a @Int of -- Is a ~ Int ?
Just Refl -> x + 1 -- If it is, we can add one.
Nothing -> x -- Otherwise, return x as-is.
Run Code Online (Sandbox Code Playgroud)
这需要一堆 GHC 扩展,并导入Data.Typeable.
有,但你不能像在计算级别那样有一个贯穿模式。也就是说,在计算层面,我可以写
f 0 = 42
f n = n-1
Run Code Online (Sandbox Code Playgroud)
一起一落,通过模式n的作品正是当没有其他模式的匹配。在类型级别,您不能这样做——甚至嵌套在其他模式中。你可以有一个匹配任何东西的模式,但不能匹配“其他任何东西”——如果你匹配任何东西,你就不能有任何其他模式。
因此,一旦您拥有要与之匹配的模式集合,就可以编写类型类和实例。所以,如果你想支持Int,Bool和列表,你可以写:
class F a where f :: a -> a
instance F Int where f = succ
instance F Bool where f = id
instance F [a] where f = id
Run Code Online (Sandbox Code Playgroud)
最后一个例子展示了我之前的意思,你可以有一个匹配任何东西的模式,但不能匹配“其他任何东西”的模式:[a]是一个很好的实例,但它排除了以后创建[Bool]实例的可能性。