具有类似gadt约束的新类型

问题描述

我了解您为什么不能这样做:

{-# LANGUAGE GADTs  #-}

newtype NG a  where MkNG :: Eq a => a -> NG a

-- 'A newtype constructor cannot have a context in its type',says GHC

那是因为'数据'构造函数MkNG并不是真正的构造函数。语言报告第4.2.3节“与代数数据类型不同,新类型的构造函数”表示:“表达式中的构造函数 N 将值强制从类型 t 转换为类型...”。 N 未举起,...”

如果要能够支持约束,则它将需要约束字典的参数位置。

现在,我引起了您的注意,我将要问这个不推荐使用的功能,您经常会看到(非常古老的)StackOverflow回答说要改用GADT:

{-# LANGUAGE DatatypeContexts  #-}             -- deprecated ~2010

newtype Eq a => NC a = MkNC a                  -- inferred MkNC :: Eq a => a -> NC a

-- nc = MkNC (id :: Int -> Int)                -- rejected no Eq instance

quux (MkNC _) = ()                             -- inferred quux :: Eq a => NC a -> ()
quuz (x :: NC a) = ()                          -- inferred quuz :: NC a -> ()

quuz的类型是DatatypeContexts的烦恼之一:因为构造函数未出现在模式匹配中,所以类型推断不能“看到”约束。)

因此,这与数据类型上的DatatypeContexts一样好(或不好)((或不取决于您的观点)。)

我的问题是:如何? MkNC再次强制一个值/取消。是否使用字典传递来应用约束?鉴于强制是纯粹的编译时效果,字典将插入哪里?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)