【问题标题】:Type constraints for polymorphic functions like lift多态函数的类型约束,如提升
【发布时间】:2015-12-11 12:12:39
【问题描述】:

所以我有这个代码

{-# LANGUAGE GeneralizedNewtypeDeriving #-}

import MonadA

data A = A

newtype MonadA a => MyStateT a b { runMyStateT :: StateT A a b }
    deriving (Functor, Applicative, Monad, MonadIO, MonadState A)

instance MonadTrans MyStateT where
    lift = MyStateT . lift

我得到编译器抱怨它无法证明lift 的签名中的mMonadA 类型,或者这就是我阅读这些神秘错误消息的方式。

Could not deduce (MonadA m) arising from a use of `MyStateT'
from the context (Monad m)
  bound by the type signature for
             lift :: Monad m => m a -> MyStateT m a

有没有办法解决这个问题?我认为我需要约束才能实例化如下:

instance MonadA a => MonadA (MyStateT a) where
    f = MyStateT . lift . f

f 的这种实现也可以吗? (由于上述错误,我没有走那么远)。我希望右侧的f 能够通过内部单子a 解析为f


编辑:确实有助于删除newtype MonadA a => MyStateT ... 中的类型约束以避免我提到的确切错误。但是,我之前将另一个错误归咎于同一件事,请考虑上面示例代码的延续(某些部分重复,现在没有类型限制):

class MonadB m where
    fB :: m ()

newtype MyStateT m a = MyStateT { runMyStateT :: StateT A m a}
    deriving (... MonadState A ...)

instance MonadTrans MyStateT where
    lift = MyStateT . lift

instance MonadA a => MonadA (MyStateT a) where
    f = lift . f

instance MonadA a => MonadB (MyStateT a) where
    fB = lift (modify (...))

错误是

Could not deduce (a ~ StateT A m0) from context (MonadA (MyStateT a), MonadA a)

在执行fB。早些时候我试过class MonadA m => MonadB m 无济于事。将aStateT A m 匹配甚至没有意义。由于MyStateTMonadState A 的一个实例,它应该可以工作,不是吗?

编辑

好的,搞定了:

fB = MyStateT (modify ...)

我太傻了。

【问题讨论】:

    标签: haskell typeclass monad-transformers type-constraints lifting


    【解决方案1】:

    解决方案是从MyStateT 定义中删除约束:

    newtype MyStateT a b { runMyStateT :: StateT A a b }
        deriving (Functor, Applicative, Monad, MonadIO, MonadState A)
    

    数据类型约束本质上是无用的,因为无论如何您都需要将它们放在函数签名中。因此,该功能实际上是deprecated

    我认为我需要约束才能实例化如下:

    不是真的; instance MonadA a => MonadA (MyStateT a) 没有它也能正常工作。

    f 的这种实现也可以吗?

    会的。请注意,当您为 MyStateT 提供了一个 MonadTrans 实例时,您实际上不需要明确地用 MyStateT 进行包装:

    instance MonadA a => MonadA (MyStateT a) where
        f = lift . f
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-06
      • 2016-08-18
      • 1970-01-01
      • 1970-01-01
      • 2013-05-31
      • 1970-01-01
      相关资源
      最近更新 更多