【问题标题】:Haskell generic type parameters resolver tool or method [duplicate]Haskell泛型类型参数解析器工具或方法[重复]
【发布时间】:2020-12-11 17:45:11
【问题描述】:

我们以这些函数的类型为例:

:t traverse
traverse
  :: (Applicative f, Traversable t) => (a -> f b) -> t a -> f (t b)

:t id
id :: a -> a

它们没有具体类型,但有泛型类型参数afbt(如果他们调用的不是泛型类型参数请纠正我)

如果我以这种方式将idtraverse 组合在一起,

:t traverse id [Just 1, Just 2, Nothing] 
traverse id [Just 1, Just 2, Nothing] :: Num b => Maybe [b]

Haskell 现在可以为类型变量afbt 绑定一些具体类型。

t = []
a = Maybe bb
f = Maybe
b = Num bb => bb

下面我手动推断参数的类型和映射,Haskell 中有没有任何方法或工具可以自动执行此操作,以便在示例中采用一些组合部分(idtraverse),提取它们一般的类型签名,并在输出时生成从泛型类型参数名称到具体推断类型的映射?

另请参阅此处的第一个示例:https://wiki.haskell.org/Type_inference 对于表达式“map ord”,了解 Haskell 如何找到实际类型与名称的绑定。

所以当我们单独查看函数时,我们只有名称afbt。但随后我们组合这些函数并提供一些额外的信息,例如[Just 1, Just 2, Nothing],并将名称afbt 映射到具体类型。

我想自动捕捉并显示这个映射。

【问题讨论】:

  • 我已经投票决定重新提出这个问题。我不知道你是否会得到一个满意的答案,但我很清楚你在问什么:自动打印出类型变量的替换编译器在实例化多态定义的类型时在类型检查期间进行推断。即,给定f :: forall x1…xn. t 类型变量x1xn 和类型t,以及一个包含f 的表达式,这将打印为x1…@ 选择的所有值(类型为Type) 987654354@。您可以在 GHC 标志 -ddump-tc-ddump-tc-ast-ddump-tc-trace 的输出中找到所需的信息。
  • 如果我关闭它时出错,请纠正我。
  • @JonPurdy,我错误地投票支持重新打开这个问题,而没有看到您的评论来自 13 小时前,而 Will Ness 仅在几分钟前关闭了这个问题,所以您可能同意(我同意) 与 Will 标记的欺骗。
  • @WillNess,我认为你没有错,即使我在问 那个 问题时有偏见,正是为了欺骗这个(可惜没有金色徽章创建一个较旧的问题被标记为重复的新问题:P)。但乔恩可能在这个问题中看到了我看不到的另一种含义。
  • @Enlico:您的问题显示了如何获取子表达式的类型;为了回答这个问题,您需要将该结果并手动将其与原始多态类型统一以获得所需的结果,例如 { fMaybe, t[], aMaybe b0, bb0 }。这适用于函数,尽管对于更复杂的子项来说不是那么好。这当然是一种到达那里的方法,只是不完全是我认为的要求——即替换。

标签: haskell types type-inference parametric-polymorphism


【解决方案1】:

我认为ft 是更多通用类型构造函数参数,因为它们作用于一个类型来给你一个类型(他们kind * -> *,其中* 表示“具体类型”)。

traverse id 不是组合,它是函数应用程序,因为您将 id 作为 参数 传递给 traversethis . thatthisthat 之间的函数组合,在数学意义上,您创建一个函数,将其(第一个)参数作为输入提供给 that,并将此应用程序的结果提供给 this .

您参考this页面中的示例,其中给出了这个

map :: (a -> b) -> [a] -> [b]
Char.ord :: (Char -> Int)

编译器能够推断出map ord的类型是[Char] -> [Int],你可以在命令行中写:t map ord来检查自己。

如果您在键入 :t traverse id 时期望具有具体类型的类似输出,您将不会得到它,原因很简单,traverse id 仍然是一个多态函数,两者都在具体类型参数和类型构造函数参数。

举一个稍微不同的例子,如果你输入:t traverse (:[]),其中(:[])的类型是a -> [a],这是traverse所期望的(Applicative f) => a -> f b的一个特例,你会得到这个输出,

traverse (:[]) :: Traversable t => t b -> [t b]

:t traverse相比,

traverse :: (Traversable t, Applicative f) => (a -> f b) -> t a -> f (t b)

告诉您traversetraverse (:[]) 中已被f === []a === b“实例化”。

【讨论】:

  • 我的意思不是函数组合,我的意思是我将两个东西(函数)组合在一起,这种组合决定了如何将名称与实际类型对应起来。
  • @Evg,那个“结合两件事”是函数应用。但是,至于您想要什么,我仍然不明白,对不起(由于问题已结束,至少其他两个人同意我的观点)。也许你可以在问题中写一个你期望从一些想要的命令或其他东西中获得的示例输出。
  • 请看这里的第一个例子:wiki.haskell.org/Type_inference for expression "map ord" Haskell 如何找到实际类型到名称的绑定。我也更新了问题。
  • @Evg,请看看我更新的答案。我强烈建议您编辑您的问题以澄清用代码您的意思。这个问题仍然是关闭的,这意味着任何路过的人都不愿意重新打开它,因为他们觉得它不清楚,就像我一样。
  • @Evg,也请看一下this question 我刚刚问过。这就是你真正想在这里问的问题吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多