Monad instance for pairs

自古美人都是妖i 提交于 2019-12-04 05:28:52

问题


This question shows an instance definition for (,) a b, where a is an instance of Monoid.

However, I don't know how to write similar thing for (,) a b, and b is an instance of Monoid? I can basically do this as long as I can write the definition:

instance Monoid b => Monad ((,) ???) where
    return a = (a,mempty)
    ~(a,b) >>= f = let (c,b1) in f a in (c,b `mappend` b1)

So the question is how to write the ??? part?

UPDATE

Actually this question is special case of a more generic problem: is it possible to write instance of type classes that act on some types that is not appear at the end? In my case, the type constructor is (,) a b, and I want to make it an instance of Monad a where a is not the last type parameter.


回答1:


We could write, for now synonyms works inappropriate for this case, so we use newtype:

newtype RevTuple b a = RevTuple { totuple :: (a , b) }

instance Monoid b => Monad (RevTuple b) where
    return a = RevTuple (a,mempty)
    (RevTuple (a,b)) >>= f = 
                 let RevTuple (c,b1) = f a in RevTuple (c,b `mappend` b1)



回答2:


You cannot. It's crucial for Monad to be polymorphic in its parameter, so if a particular monadish thing only makes sense for monoids, it's not a monad.

For example, return :: Monad m => a -> m a. There's no way you can add an extra constraint to the signature of return.



来源:https://stackoverflow.com/questions/19196333/monad-instance-for-pairs

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!