I'm learning scalaz these days. When I compare scalaz with Haskell, I find that it's hard to customize my own monad transformer.
The code I can do in Haskell like this:
newtype Box a = Box a deriving Show
-- Monad instance of Box, it's simple, I pass it..
newtype BoxT m a = BoxT {runBoxT :: m (Box a)}
instance (Monad m) => Monad (BoxT m) where
return a = BoxT $ return $ Box a
x >>= f = BoxT $ do
(Box v) <- runBoxT x
runBoxT $ f v
instance (Monad m) => Applicative (BoxT m) where
pure = return
(<*>) = ap
instance (Monad m) => Functor (BoxT m) where
fmap = liftM
How can I do the same thing in scalaz ? I have tried many ways, but it looks like I can not figure out the type of scala's generic, like this:
case class Box[A](value:A)
case class BoxT[M[_],A](run: M[Box[A]])
implicit val monad = Monad[BoxT] { // goes wrong, type `BoxT[M[_],A]` doesn't match F[_]
... //don't know how to override functions..
}
?
or*
like it done for OptionT in cats? Like line 284 here. github.com/typelevel/cats/blob/master/core/src/main/scala/cats/… Also you can look at type lambdas underscore.io/blog/posts/2016/12/05/type-lambdas.html – Iva Kam?
and'
, but the compiler saysnot found: type *
, I have no idea.. My scala version is 2.13.1, sbt is 1.2.8, java is openjdk-11 – Jacky Wong