【问题标题】:Type families: top level vs. associated类型族:顶级与关联
【发布时间】:2015-01-31 11:42:23
【问题描述】:

我刚刚开始学习类型族。 GHC 文档指出顶级和关联类型系列具有相同的功能,但我正在编写的代码在顶级中的行为与关联系列时的行为不同。这编译并运行良好:

{-# LANGUAGE TypeFamilies #-}
module Test where

-- type family R a
-- type instance R Maybe = Int

class C' a where
  type R a
  getInt' :: a Int
  getBool' :: R a -> a Bool

instance C' Maybe where
  type R Maybe = Int
  getInt' = Just 3
  getBool' i = Just $ i < 10

printer :: IO ()
printer = print $ (getBool' 5 :: Maybe Bool)

但这给了我一个类型错误:

{-# LANGUAGE TypeFamilies #-}
module Test where

type family R a
type instance R Maybe = Int

class C' a where
  -- type R a
  getInt' :: a Int
  getBool' :: R a -> a Bool

instance C' Maybe where
  -- type R Maybe = Int
  getInt' = Just 3
  getBool' i = Just $ i < 10

printer :: IO ()
printer = print $ (getBool' 5 :: Maybe Bool)

这些和我一模一样;为什么一个编译另一个不编译?

【问题讨论】:

  • 关联类型族的不同之处仅在于编译器期望每个类实例中有 1 个或多个类型实例。当文档说“相同的功能”时,这意味着相同声明的语义相同,但您仍然必须将声明放在正确的位置。 “关联”类型族的目的是提醒实现者他们必须定义该类型实例。

标签: haskell types


【解决方案1】:

如果您对类型进行注释,则第二个有效:

type family R (a :: * -> *)

我认为没有任何理由只为关联的类型族推断出正确的类型。

【讨论】:

  • 为关联的类型族推断出正确的类型,因为它在使用该类型族的函数中存在附加类型信息,以及来自类声明的类型a。例如,它看到a Int 必须是类型* 的有效类型,您可以从中推断出a :: * -&gt; *。如果类型族没有关联,编译器显然无法访问该信息,因此它为类型族提供默认类型:* -&gt; *
  • 我不同意编译器显然无法访问该信息。它似乎在该文件中可用,只是出于任何原因都没有使用(没有人要求它,它太难实现,使用类型族帮助确定种类等会太混乱)
  • 我同意这在任何意义上都不是不可能。我的意思是,编译器不会查看类型族的使用站点来确定其类型;这样做可能真的没有意义,尤其是因为解决方案非常简单。
猜你喜欢
  • 1970-01-01
  • 2016-10-28
  • 1970-01-01
  • 2023-04-10
  • 2013-05-06
  • 1970-01-01
  • 2018-10-14
  • 2020-02-28
  • 1970-01-01
相关资源
最近更新 更多