haskell - 为什么这个类型不检查?

标签 haskell

class Foo t where
  foo :: t

bar :: Binary t => t -> ()
bar = undefined

repro :: (Binary t, Foo t) => Proxy t -> ()
repro _proxy =
  bar (foo :: t)

编译器提示:

  • 无法推断出因使用“bar”而产生的(二进制 t0) 从上下文:(二进制 t,Foo t) 由类型签名绑定(bind): 复制::forall t。 (二进制 t, Foo t) => 代理 t -> ()

  • 无法推断出因使用“foo”而产生的(Foo t2) 从上下文:(二进制 t,Foo t) 由类型签名绑定(bind): 复制::forall t。 (二进制 t, Foo t) => 代理 t -> ()

具体来说,我很惊讶它没有看到我将 t 传递给 bar,并创建了 t0 类型变量。 t2 更加神秘,因为 foo 显式注释为 t 类型。

最佳答案

默认情况下,类型变量的作用域不是这样的。函数签名中的 t 和函数体中的 t 不相同。您的代码相当于:

repro :: (Binary t, Foo t) => Proxy t -> ()
repro _proxy =
  bar (foo :: a)

您需要启用 ScopedTypeVariables 扩展,并添加显式 forall t

{-# LANGUAGE ScopedTypeVariables #-}

repro :: forall t. (Binary t, Foo t) => Proxy t -> ()
repro _proxy =
  bar (foo :: t)

关于haskell - 为什么这个类型不检查?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51446524/

相关文章:

haskell - LiftIO 的目的是什么?

haskell - 我如何告诉 cabal 为我的程序的依赖项之一指定依赖项?

haskell - Haskell 如何推断类型类的定义?

haskell - 创建数据类型时派生意味着什么?

haskell - 将两个 Int 值相除以获得 Float 的正确方法是什么?

parsing - 具有存在量化的解析器的类型签名

Haskell 函数从左到右

haskell - 秒差距输入意外结束

haskell - 更改用于在 GHCi 中运行 "shell commands"的 shell

java - 在 Java 中使用命令提示符