问题描述
我刚刚理解了类的定义MonadReader
class Monad m => MonadReader r m | m -> r where
...
阅读了Haskell中的函数依赖文档,现在我可以理解| m -> r
指定类型变量r
由m
唯一决定。根据我目前所见的几个典型的MonadReader实例(例如Reader
),我认为这个要求是合理的,但在我看来,即使没有这个函数依赖子句,我们仍然可以定义像Reader
这样的实例。
推荐答案
需要以更方便用户的方式进行类型推理。
例如,如果没有函数,这将无法编译:
action :: ReaderT Int IO ()
action = do
x <- ask
liftIO $ print x
要编译上述代码,我们需要编写
action :: ReadertT Int IO ()
action = do
x <- ask :: ReadertT Int IO Int
liftIO $ print x
这是因为,没有函数,编译器无法推断x
是Int
。毕竟,一个单体ReadertT Int IO
可能有多个实例
instance MonadReader Int (ReaderT Int IO) where
ask = ReaderT (i -> return i)
instance MonadReader Bool (ReaderT Int IO) where
ask = ReaderT (i -> return (i != 0))
instance MonadReader String (ReaderT Int IO) where
ask = ReaderT (i -> return (show i))
-- etc.
因此程序员必须提供一些强制x :: Int
的注释,否则代码不明确。