表示 StateT Functor 实例定义的替代方法

Alternative way to express StateT Functor instance definition

我通过以下方式为 StateT 实现了 Functor 实例

import Data.Tuple (swap)

newtype StateT s m a =
    StateT { runStateT :: s -> m (a, s) }

instance Functor m => Functor (StateT s m) where
    fmap f (StateT g) = StateT $ \s -> fmap (fmapSwapTwice f) (g s)
        where fmapSwapTwice f tup = swap $ f <$> swap tup

但我并不完全满意我的解决方案,因为它需要我从 Data.Tuplefmap 导入 swap在元组上两次,以便将 f 应用于第一个元素。

对我来说,这似乎是一个足够常见的模式,它有自己的抽象,或者可能有另一种方式来表达我想不到的 Functor 实例,它不需要 swap 根本

利用元组的 Bifunctor 实例。使用 Data.Bifunctor.first 而不是 fmapSwapTwice.