你如何在Haskell中使用TypeApplications?

Sho*_*hou 13 haskell types ghc language-extension

随着-XTypeApplications在GHC 8.0,你可以显式指定类型的@函数参数的前面.它准确指定了哪些类型,特别是在@引入多个类型时?

Sho*_*hou 13

如果你看一个函数的类型

elem :: (Foldable t, Eq a) => a -> t a -> Bool
Run Code Online (Sandbox Code Playgroud)

我们看到它有两个多态变量,ta.这些变量是@类型应用程序指定的变量.似乎在上下文中引入的变量 - 类型类约束在哪里 - 影响顺序,因此第一个@指定了t,第二个指定了a.在没有上下文变量的函数中

const :: a -> b -> a
Run Code Online (Sandbox Code Playgroud)

顺序更明显,a是第一个,b也是第二个.正如Cactus在上面的评论中提到的,您也可以使用显式的foralls来自己指定顺序.

myConst :: forall b a. a -> b -> a
Run Code Online (Sandbox Code Playgroud)

现在第一个类型的应用程序将指定b第二个类型a.

您可能会遇到需要指定类型的问题,尤其是在使用重载字符串或列表时

elem c "abc...xyz" -- What string type is this?
elem c ['a' .. 'z'] -- What list constructor is this?
Run Code Online (Sandbox Code Playgroud)

因此我们使用显式类型应用程序

elem @[] @Char c ['a' .. 'z']
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我们只需要指定@[]并说"这是一个[]列表类型构造函数",因为GHC是Char从列表元素推断出来的,因此@Char这里可以省略.

如果GHC能够推断的多态参数恰好是第一个你可以利用-XPartialTypeSignatures它允许你使用_类型签名,包括类型应用程序签名,告诉GHC只是推断[部分]类型,以减少冗长.

f @_ @[]
Run Code Online (Sandbox Code Playgroud)

  • 对我来说,似乎在不止一种类型应用程序之后,与 `::` 相比的任何可读性优势都消失了,特别是因为人们必须回忆类型约束顺序。至少在这种情况下,我认为 `elem c ['a' .. 'z'] :: [Char]` 更具可读性。 (2认同)