为什么要定义MonadReader需要FunctionalDependency?

问题描述 投票:8回答:3

我是Haskell的新手,我刚刚设法了解了类MonadReader的定义>

class Monad m => MonadReader r m | m -> r where
...

[在阅读Haskell中的函数依赖文档之后,现在我可以理解| m -> r指定类型变量rm唯一决定。基于目前为止我所见过的MonadReader的几个典型实例,我认为这一要求是合理的(例如Reader),但在我看来,即使没有此功能依赖项,我们仍然可以定义类似Reader的实例。

我的问题是,为什么在MonadReader的定义中需要功能依赖?从某种意义上说,在没有MonadReader不能正确定义MonadReader的情况下,这在功能上是必需的吗?还是仅是一种限制,限制了MonadReader的使用方式,以便MonadReader的实例都能以某种预期的方式运行?] >

我是Haskell的新手,我只是设法了解MonadReader类Monad m的定义=> MonadReader r m | m-> r其中...阅读了功能文档...

haskell monads ghc type-systems
3个回答
2
投票

需要以对用户更方便的方式使类型推断起作用。

例如,如果没有资助者,它将无法编译:


1
投票

我认为混乱的根源在于]的定义>

class Monad m => MonadReader r m | m -> r where
  {- ... -}

0
投票

这并不是真正的答案,但是评论太长了。没错,可以定义MonadReader类,这是正确的。特别地,每种方法的类型签名确定每个类参数。定义更好的层次结构很有可能。

class MonadReaderA r m where
  askA :: m r
  askA = readerA id

  readerA :: (r -> a) -> m a
  readerA f = f <$> askA

-- This effect is somewhat different in
-- character and requires special lifting.
class MonadReaderA r m => MonadReaderB r m where
  localB :: (r -> r) -> m a -> m a

class MonadReaderB r m
  => MonadReader r m | m -> r

ask :: MonadReader r m => m r
ask = askA

reader
  :: MonadReader r m
  => (r -> a) -> m a
reader = readerA

local
  :: MonadReader r m
  => (r -> r) -> m a -> m a
local = localB
© www.soinside.com 2019 - 2024. All rights reserved.