6
我偶尔遇到这个问题,最后想问一下是否有一个共同的解决方案或模式。 是否有可能在嵌套上下文引用中创建一个类型变量来自外部上下文的类型?例如,Haskell引用一个类型变量
foo :: a -> ... -> ..
foo = ...
where bar :: a -> ...
现在bar
的a
比富的a
不同。通常情况下,这是我想要的,但偶尔它会让生活变得困难,我需要让它们变得一样。我使用肮脏的技巧来迫使类型检查者在过去统一这两种技巧,但偶尔也会受到挫折。这是我最新的例子(一个Parsec函数),它激励我最终提出这个问题。
data Project = ... deriving Enum
data Stuff = ...
pProject :: Monad m => P m Stuff
pProject = do
stuff <- pStuff
...
convert stuff <$> pEnum :: P m Project
pEnum :: (Monad m, Enum a) => String -> P m a
pEnum = ...
的convert
函数需要一个类型,因此,我必须指定注释:: P m Project
。 但是,这意味着我还必须介绍m
,这不幸与功能签名中的m
不一样。类型检查报告,这有:
无法推断
Monad m1
从使用pEnum
从上下文Monad m
产生有引用函数签名的m
没有一些丑陋的黑客攻击的方法吗?(一个丑陋的黑客是将不会得到执行,但存在只是为了统一这两种类型的伪码。)
感谢您指出'ScopedTypeVariables'只适用于具有显式'forall'的签名。难怪它似乎几乎从未工作过...... – Cirdec 2014-12-06 00:51:05
这并不完全正确 - 'ScopedTypeVariables'使类型变量在类声明中作用域,即使没有'forall'也是如此。所以它可以改变一个人为设计的Haskell 2010程序的含义。 – shachaf 2014-12-06 01:52:07