【发布时间】:2015-05-19 17:01:39
【问题描述】:
我正在尝试构建一个库以根据某些上下文填充模板。
相关数据类型为ContextNode 和Context。
data ContextNode m = ContextText Text
| ContextSub (Context m)
type Context m = (Text -> m (Maybe (ContextNode m)))
我定义了一个类型类ContextGenerator,以便能够使用泛型派生一些上下文,例如数据类型。
class ContextGenerator m a where
clookup :: a -> Text -> m (Maybe (ContextNode m))
Context 应该是ContextGenerator 的一个实例
instance (MonadIO m) => ContextGenerator m (Context m) where
clookup a s = a s
创建上下文的一些代码
mkContext :: MonadIO m => Text -> ContextNode m -> Context m
mkContext s n = \s' -> if s' == s then return (Just n) else return Nothing
当我执行以下操作时不起作用(在我启用 OverloadedStrings 和 FlexibleContexts 的 repl 中)
> let ctx = mkContext "hello" (ContextText "world")
> clookup ctx "hello"
Could not deduce (Control.Monad.IO.Class.MonadIO m0)
from the context (Control.Monad.IO.Class.MonadIO m1,
ContextGenerator m (Context m1))
bound by the inferred type for ‘it’:
(Control.Monad.IO.Class.MonadIO m1,
ContextGenerator m (Context m1)) =>
m (Maybe (ContextNode m))
at <interactive>:18:1-19
The type variable ‘m0’ is ambiguous
When checking that ‘it’ has the inferred type
it :: forall (m :: * -> *) (m1 :: * -> *).
(Control.Monad.IO.Class.MonadIO m1,
ContextGenerator m (Context m1)) =>
m (Maybe (ContextNode m))
Probable cause: the inferred type is ambiguous
在我看来,GHC 推断实例定义中的两个m 是不同的,对吗?我如何告诉 GHC 这些应该是一样的?
【问题讨论】:
-
我认为最简单的方法可能是将functional dependencies 用于您的
ContextGenerator,例如class ContextGenerator m a | a -> m where ...
标签: haskell