防止类型统一

迈克·伊兹比基(Mike Izbicki)

鉴于此包装整数:

newtype MyProxy a = MyProxy Int

mkProxy :: Int -> MyProxy a
mkProxy a = MyProxy a

addProxy :: MyProxy a -> MyProxy a -> MyProxy  a
addProxy (MyProxy a1) (MyProxy a2) = MyProxy $ a1+a2

我可以执行以下操作:

a = mkProxy 1
b = mkProxy 2
c = addProxy a b

因为幻象参数将是统一的。但是我想防止这种统一,并在行上导致类型错误c

ST monad使用rank2类型来实现类似的效果。通过更改的类型,我可能可以做类似的事情addProxy但是我特别不想这样做。我想以a某种方式注释类型变量,以防止其在addProxy调用中统一

在Haskell中这可能吗?这样的选择有危险的理由吗?


编辑:

让我详细说明部分解决方案(-XScopedTypeVariables)。我可以将上面的代码重写为:

c :: forall a1 a2. MyProxy a1
c = addProxy a b
    where
        a = mkProxy 1 :: MyProxy a1
        b = mkProxy 2 :: MyProxy a2

这正确地导致类型错误,c因为a1并且a2无法统一。但是,这有两个缺点:ab不能在顶级定义; 并且您必须明确指定的结果类型mkProxy

有可能解决这些缺陷吗?

丹尼尔·格拉泽(Daniel Gratzer)

不,您不能,至少在不指定之前mkProxy

ST monad的工作方式是要求转义计算生成某种类型的内容forall s. ST s a,以防止s在中自由出现a

但是,在您的情况下,您要执行两个相同的计算,因此为每个计算生成不同的类型可能会被用来做邪恶的事情。例如,如果mkInt 1每次调用时生成不同的类型,

class Evil a b c | a, b -> c where
  foo :: a -> b -> c

let x = mkProxy 1 in foo x x

会不同于

 foo (mkProxy 1) (mkProxy 1)

并且我们在代码中丢失了一些非常好的属性。

然而,我们可以做一些额外的腿部工作,并在事实ab不能统一明确

 {-# LANGUAGE DataKinds #-}

 data Nat = S Nat | Z
 data Proxy (n :: Nat) a = Proxy a

 based :: a -> Proxy Z a
 based = Proxy

 fresh :: Proxy n a -> a -> Proxy (S n) a
 fresh (Proxy _) a = Proxy a

所以现在你需要做类似的事情

a = based 1

b = fresh a 2

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

防止类型统一

来自分类Dev

如何统一这些类型?

来自分类Dev

统一记录类型

来自分类Dev

多参数类型类的类型统一

来自分类Dev

类型中要统一的类型变量

来自分类Dev

类型中要统一的类型变量

来自分类Dev

开放对象类型过早统一

来自分类Dev

递归数据类型的统一

来自分类Dev

Isabelle类型统一/推断错误

来自分类Dev

注册类型时出现统一异常

来自分类Dev

统一宏中的通用类型

来自分类Dev

开放对象类型过早统一

来自分类Dev

防止统一产生的游戏对象重叠

来自分类Dev

FunctionalDependencies不会统一唯一标识的类型

来自分类Dev

基本类型的统一初始化语法?

来自分类Dev

如何统一更改GUI中的字体类型

来自分类Dev

数组和类聚合类型的统一初始化

来自分类Dev

统一算法可以推断具体类型

来自分类Dev

Purescript-无法统一类型

来自分类Dev

利用值类型和引用的统一语法

来自分类Dev

类型参数的统一和隐式转换

来自分类Dev

统一的参数传递和类型安全与Java泛型

来自分类Dev

如何统一更改GUI中的字体类型

来自分类Dev

为什么类型/类统一主要在python中

来自分类Dev

统一算法推断出太具体的类型

来自分类Dev

基本类型的统一初始化语法?

来自分类Dev

为什么此类型类实例无法统一?

来自分类Dev

类型不能使用类型类和类型族来统一

来自分类Dev

统一类型和非类型模板参数