背景:我正在尝试创建一个错误单子,它还可以跟踪警告列表,类似于这样:
data Dangerous a = forall e w. (Error e, Show e, Show w) =>
Dangerous (ErrorT e (State [w]) a)
即 Dangerous a
是一种操作,其结果为 (Either e a, [w])
,其中 e
是可显示的错误,w
也是可显示的。
问题在于,我似乎无法真正运行这个东西,主要是因为我不太理解存在类型。观察:
runDangerous :: forall a e w. (Error e, Show e, Show w) =>
Dangerous a -> (Either e a, [w])
runDangerous (Dangerous f) = runState (runErrorT f) []
这段代码无法编译,因为:
Could not deduce (w1 ~ w)
from the context (Error e, Show e, Show w)
...
`w1' is a rigidtype variable bound by
a pattern with constructor
Dangerous :: forall a e w.
(Error e, Show e, Show w) =>
ErrorT e (State [w]) a -> Dangerous a
...
`w' is a rigid type variable bound by
the type signature for
runDangerous :: (Error e, Show e, Show w) =>
Dangerous a -> (Either e a, [w])
我迷惑了,w1是什么?为什么我们不能推断出它是~w
?
Dangerous e w a
呢?如果我理解你想要实现的内容(这很可能不是),那么这里没有必要使用存在类型。 - ehirdDangerous OptError OptWarning [Option]
,在模板文件中说Dangerous TemplateError TemplateWarning Template
很烦人,因为它们都只是要被“show”出来。我试图删除很多样板代码并学习一些东西,这当然不是必要的。 - So8res