haskell - 什么干扰了我的作用域类型变量?
问题描述
过去几天我一直害怕问这个问题,因为它的特点是我没有注意到一个小错误,所以如果是这种情况,我真诚地道歉。
我正在尝试编写自己的scanr
作为我正在编写的库的一部分。代码如下所示:
-- Language Extensions for the file --
{-# Language BangPatterns #-}
{-# Language FlexibleInstances #-}
{-# Language FlexibleContexts #-}
{-# Language QuantifiedConstraints #-}
{-# Language UndecidableInstances #-}
{-# Language ScopedTypeVariables #-}
rightScan ::
( Foldable f
)
=> forall a b . (a -> b -> b) -> b -> f a -> NonEmpty [] b
rightScan g start as = start :| reverse (rightFold addOn [] as)
where
addOn :: a -> [b] -> [b]
addOn new (c : cs) = g new c : c : cs
addOn new [] = [g new start]
(myNonEmpty
实际上是由一个容器参数化的(本例中[]
),myNonEmpty []
相当于传统的NonEmpty
。)
现在这有两个错误:
• Couldn't match expected type ‘a’ with actual type ‘a1’
‘a1’ is a rigid type variable bound by
the type signature for:
addOn :: forall a1 b1. a1 -> [b1] -> [b1]
和非常相似的
• Couldn't match expected type ‘b’ with actual type ‘b1’
‘b1’ is a rigid type variable bound by
the type signature for:
addOn :: forall a1 b1. a1 -> [b1] -> [b1]
现在这些错误很容易理解。它认为a
in的签名与inrightScran
的签名不同,而与 的签名相同。但是,我已经对类型变量进行了限定,并且这两个变量都是在父级中引入的。a
addOn
b
forall
现在我可以删除签名addOn
来解决问题,但我完全困惑为什么作用域类型变量在这里不起作用。
所以问题是:我在这里的作用域类型变量做错了什么?
解决方案
问题在于forall
. 它需要出现在约束之前并列出所有类型变量,包括f
. forall f a b. (Foldable f) => ...
.
按照您编写的方式,forall 的作用域并不涵盖整个类型,因此它绑定的类型变量被认为是该类型的本地变量。这是由 启用的RankNTypes
,它包含在QuantifiedConstraints
.
推荐阅读
- python-3.x - Python:如何获得所需的列表?
- c# - Godot 发射信号在另一个场景中定义
- c - 通过编写循环优化 C 中的基本嵌套循环
- proxy - gcloud登录网络连接失败问题
- powershell - start-sleep 将冻结 Register-ObjectEvent 动作脚本块
- powershell - Powershell:滞后函数优于属性
- flutter - 如何使文本在 Flutter 中的所有屏幕尺寸上都显示相同
- php - 如何使用 Kubernetes API 处理流响应?
- python - 破折号 DataTable 中的 JSON 数据无效参数
- typescript - TypeScript:“动态值”分配的变量类型?