【问题标题】:How do you use TypeApplications in Haskell?你如何在 Haskell 中使用 TypeApplications?
【发布时间】:2017-03-09 13:48:36
【问题描述】:

使用 GHC 8.0 中的 -XTypeApplications,您可以使用 @ 前面的函数参数显式指定类型。它具体指定了哪些类型,尤其是在引入多个@ 时?

【问题讨论】:

  • 如果你打算使用TypeApplications,我认为使用ExplicitForAll(或包含它的TypedScopeVariables)是个好主意,因为在这种情况下没有歧义:如果你有例如const :: forall a b. a -> b -> a,那么第一个@-参数将用于a,第二个用于b
  • ScopedTypeVariables

标签: haskell types ghc language-extension


【解决方案1】:

如果你看一下函数的类型

elem :: (Foldable t, Eq a) => a -> t a -> Bool

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

const :: a -> b -> a

顺序更明显,a 第一,b 第二。正如上面评论中提到的 Cactus,您还可以使用显式 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']

在这种情况下,我们只有 指定 @[] 并说“这是一个 [] 列表类型构造函数”,因为 GHC 从列表元素推断 Char,所以 @Char此处可省略。

如果 GHC 能够推断出多态参数恰好先出现,您可以利用 -XPartialTypeSignatures,它允许您在类型签名(包括类型应用程序签名)中使用 _,告诉 GHC 仅推断 [part of the] 类型, 让事情变得不那么冗长。

f @_ @[]

【讨论】:

  • 在我看来,在不止一个类型应用程序之后,与:: 相比的任何可读性优势都消失了,尤其是因为必须回忆类型约束顺序。至少在这种情况下,我认为elem c ['a' .. 'z'] :: [Char] 更具可读性。
猜你喜欢
  • 1970-01-01
  • 2011-12-07
  • 1970-01-01
  • 2011-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多