自定义monoid与WriterT

DBS*_*DBS 1 monads haskell monad-transformers monoids

我正在尝试使用自定义数据类型实现WriterT.我已经将runone作为runWriterT的要求实现了.但我无法编译代码.我收到一个错误

无法推断(半群(Env a))来自上下文中的实例声明的超类:Num a

import Control.Monad
import Control.Monad.Trans.Reader
import Control.Monad.IO.Class
import Control.Monad.Trans.Writer
import Control.Monad.Trans
import Data.Monoid

newtype Env a = Env { getEnv :: a  }  deriving (Eq, Ord, Read, Show)


instance Num a => Monoid (Env a) where
  mempty = Env 0
  Env x  `mappend` Env y = Env (x + y)


writeSomething :: (Num a) => WriterT (Env a) IO ()
writeSomething = do
  tell $ Env 1
  tell $ Env 3
Run Code Online (Sandbox Code Playgroud)

Dan*_*ner 5

在最近的GHC中,Semigroup是一个超类Monoid,所以要Monoid正确创建一个实例,你还必须创建一个实例Semigroup.幸运的是,它通常很短:

instance Num a => Semigroup (Env a) where (<>) = mappend
Run Code Online (Sandbox Code Playgroud)

  • 是的,但更好的是定义`Env x <> Env y = Env(x + y)`并且从不谈论`mappend`(["这个方法是多余的并且具有默认实现`mappend ='(<>)' `自base-4.11.0.0"](http://hackage.haskell.org/package/base-4.11.1.0/docs/Data-Monoid.html#v:mappend)). (5认同)