当不太严格的 Functor 约束就足够了时,为什么还要存在 Monad 类型类约束?

问题描述 投票:0回答:1

我正在查看

StateT
monad 转换器的源代码

有两个函数

execStateT
evalStateT
在其定义中具有
Monad m
约束:

evalStateT :: Monad m => StateT s m a -> s -> m a
evalStateT m s = do
  ~(a, _) <- runStateT m s
  return a

execStateT :: Monad m => StateT s m a -> s -> m s
execStateT m s = do
  ~(_, s') <- runStateT m s
  return s'

使用

Functor
约束的实现不也可以工作吗?

evalStateT :: Functor m => StateT s m a -> s -> m a
evalStateT = (fmap fst .) . runStateT

execStateT :: Functor m => StateT s m a -> s -> m s
execStateT = (fmap snd .) . runStateT

施加更严格的约束是否有原因?

haskell
1个回答
0
投票

施加更严格的约束是否有原因?

很难说,但我想到两个原因:

  1. 将其用作

    Functor
    没有多大意义:单子转换器只有使用它来转换单子才有意义。因此,最终
    evalStateT
    将(几乎)始终与
    m
    Monad
    实例一起工作,因为首先构造
    StateT s m a
    的事物需要
    m
    成为
    Monad
    ;和

  2. Monad
    类型约束早在 2009 年 1 月就已在
    transformers-0.0.0.0
    中实现。当时 Functor-Applicative-Monad 提案尚未提出(那是在 2014 年)。所以这意味着到那时,
    Monad
    不是
    Applicative
    的子类,
    Applicative
    也不是
    Functor
    的子类。因此,类型 T 可以是
    Monad
    的实例,而不是
    Functor
    Applicative
    的实例。

    因此,通过添加

    Functor
    作为类型约束,实际上常常会让情况变得更糟:作为
    Monad
    实例的某些类型不是
    Functor
    s yet 的实例,因此您可以排除某些类型对于
    StateT
    仍然有用。事实上,
    Monad
    类型不需要是
    Applicative
    Functor
    的实例,这一事实总是有点错误,但需要一段时间才能消除损坏。

© www.soinside.com 2019 - 2024. All rights reserved.