您如何在 Haskell 中使用 TypeApplications?
How do you use TypeApplications in Haskell?
使用 GHC 8.0 中的 -XTypeApplications
,您可以使用 @
前面的函数参数显式指定类型。它具体指定了哪些类型,特别是当引入多个 @
时?
如果你看一下函数的类型
elem :: (Foldable t, Eq a) => a -> t a -> Bool
我们看到它有两个多态变量,t
和 a
。这些变量是 @
类型应用程序指定的。似乎在上下文中引入的变量——类型类约束所在的位置——会影响顺序,因此第一个 @
指定 t
,第二个 a
。在没有上下文变量的函数中
const :: a -> b -> a
顺序比较明显,a
第一,b
第二。正如上面评论中提到的仙人掌,你也可以使用显式的foralls来自己指定顺序。
myConst :: forall b a. a -> b -> a
现在第一种应用程序将指定 b
,第二种应用程序将指定 a
。
您可能 运行 遇到需要指定类型的问题,特别是当您使用重载的字符串或列表时
elem c "abc...xyz" -- What string type is this?
elem c ['a' .. 'z'] -- What list constructor is this?
因此我们使用显式类型应用程序
elem @[] @Char c ['a' .. 'z']
在这种情况下,我们只有 来指定 @[]
并说 "this is a []
list type constructor" 因为 GHC 从列表元素中推断出 Char
,所以@Char
这里可以省略
如果 GHC 能够推断的多态参数碰巧先出现,您可以利用 -XPartialTypeSignatures
,它允许您在类型签名(包括类型应用程序签名)中使用 _
,告诉 GHC 只推断[部分] 类型,使事情不那么冗长。
f @_ @[]
使用 GHC 8.0 中的 -XTypeApplications
,您可以使用 @
前面的函数参数显式指定类型。它具体指定了哪些类型,特别是当引入多个 @
时?
如果你看一下函数的类型
elem :: (Foldable t, Eq a) => a -> t a -> Bool
我们看到它有两个多态变量,t
和 a
。这些变量是 @
类型应用程序指定的。似乎在上下文中引入的变量——类型类约束所在的位置——会影响顺序,因此第一个 @
指定 t
,第二个 a
。在没有上下文变量的函数中
const :: a -> b -> a
顺序比较明显,a
第一,b
第二。正如上面评论中提到的仙人掌,你也可以使用显式的foralls来自己指定顺序。
myConst :: forall b a. a -> b -> a
现在第一种应用程序将指定 b
,第二种应用程序将指定 a
。
您可能 运行 遇到需要指定类型的问题,特别是当您使用重载的字符串或列表时
elem c "abc...xyz" -- What string type is this?
elem c ['a' .. 'z'] -- What list constructor is this?
因此我们使用显式类型应用程序
elem @[] @Char c ['a' .. 'z']
在这种情况下,我们只有 来指定 @[]
并说 "this is a []
list type constructor" 因为 GHC 从列表元素中推断出 Char
,所以@Char
这里可以省略
如果 GHC 能够推断的多态参数碰巧先出现,您可以利用 -XPartialTypeSignatures
,它允许您在类型签名(包括类型应用程序签名)中使用 _
,告诉 GHC 只推断[部分] 类型,使事情不那么冗长。
f @_ @[]