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)
编译器抱怨:
无法从上下文中推断出 (Binary t0) 由使用“bar”引起的:(Binary t, Foo t) 受类型签名的约束:repro :: forall t。(二进制 t, Foo t) => 代理 t -> ()
无法从上下文中推断出 (Foo t2) 是由使用 'foo' 引起的:(Binary t, Foo t) 受类型签名的约束:repro :: forall t。(二进制 t, Foo t) => 代理 t -> ()
具体来说,我很惊讶它没有看到我传递t
给bar
,并创建了一个t0
类型 var。t2
更神秘,因为foo
被显式地注解了 type 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)
推荐阅读
- laravel - 在 Vue.js 和 Laravel 中上传多张图片
- javascript - 从可执行文件 (.exe) 中恢复 NodeJS 代码
- python - Python:Pillow 无法正确呈现高棉语
- swift - 如何将 searchController 与 searchResultsController 一起使用?
- jolt - 颠簸,映射到数组
- r - 如何在R中使用频率表获得中位数?
- javascript - 仅重新渲染由循环生成的特定元素
- mysql - MySQL SELECTs 如何加入
- c++ - 有没有办法在不知道 C++ 大小的情况下迭代枚举
- sharepoint - Sharepoint 管理员活动日志