Comments (3)
And same kind of code in Haskell, it works fine :
newtype Req = Req String deriving Show
data Res a = SkipRes | NonRes | SomeRes [a] deriving Show
instance Monoid (Res a) where
mempty = NonRes
SkipRes `mappend` _ = SkipRes
_ `mappend` SkipRes = SkipRes
NonRes `mappend` NonRes = NonRes
NonRes `mappend` SomeRes a = SomeRes a
SomeRes a `mappend` NonRes = SomeRes a
SomeRes a `mappend` SomeRes b = SomeRes $ a ++ b
mconcat = foldl1 mappend
instance Semigroup (Res a) where
(<>) = mappend
newtype AbstractAction a = AbstractAction {runAbstractAction :: Req -> (a, Req)}
instance Monad AbstractAction where
return a = AbstractAction $ \r -> (a,r)
m >>= f = AbstractAction $ \r ->
let (a,r1) = runAbstractAction m r in
runAbstractAction (f a) r1
instance Applicative AbstractAction where
pure = return
(<*>) = ap
instance Functor AbstractAction where
fmap = liftM
type Action a = AbstractAction (Res a)
action :: (Req -> (Res a, Req)) -> Action a
action = AbstractAction
runAction :: Action a -> (Req -> (Res a,Req))
runAction = runAbstractAction
first :: Action String
first = action f
where
f r@(Req []) = (NonRes, Req " with 1 ")
f r@(Req "skip") = (SkipRes, Req " with 1 ")
f r@(Req as) = (SomeRes ["not empty req"], Req " with 1 ")
second :: Action String
second = action $ \(Req s) ->
let nr = Req $ s ++ " with 2" in
(SomeRes $ ["get req:" ++ s], nr)
three :: Action String
three = do
f <- first -- f: Res String
s <- second -- s: Res String
return $ f <> s -- works ok,
from scalaz.
This is not a bug because Scala type
is not equivalent to Haskell newtype
.
I think you should create case class AbstractAction[A]
- type AbstractAction[A] = Req => (A, Req)
+ case class AbstractAction[A](run: Req => (A, Req))
implicit val monad = new Monad[AbstractAction] {
- override def point[A](a: => A): AbstractAction[A] = r => (a, r)
+ override def point[A](a: => A): AbstractAction[A] = AbstractAction(r => (a, r))
- override def bind[A, B](fa: AbstractAction[A])(f: A => AbstractAction[B]): AbstractAction[B] = (r:Req) => {
- val (a,r1) = fa(r)
- f(a)(r1)
- }
+ override def bind[A, B](fa: AbstractAction[A])(f: A => AbstractAction[B]): AbstractAction[B] = AbstractAction((r:Req) => {
+ val (a,r1) = fa.run(r)
+ f(a).run(r1)
+ })
}
type Action[A] = AbstractAction[Res[A]]
- def first = { (r: Req) =>
+ def first = AbstractAction{ (r: Req) =>
if (r.value.isEmpty) (NonRes, Req(" with 1 "))
else if (r.value == "skip") (SkipRes, Req(" with 1 "))
else (SomeRes(List("not empty req")), Req(" with 1 "))
}
- def second = (r:Req) => (SomeRes(List("get req:"+r.value)), Req(r.value + " with 2 "))
+ def second = AbstractAction((r:Req) => (SomeRes(List("get req:"+r.value)), Req(r.value + " with 2 ")))
import scalaz._, Scalaz._
sealed case class Req(value:String) //stand for request
sealed trait Res[+A] { self => //stand for response
def <>[B>:A](f2: Res[B]):Res[B] = (self,f2) match {
case (SkipRes,_) => SkipRes
case (_,SkipRes) => SkipRes
case (NonRes,NonRes) => NonRes
case (NonRes,a@SomeRes(_)) => a
case (a@SomeRes(_),NonRes) => a
case (SomeRes(a),SomeRes(b)) => SomeRes(a ++ b)
}
}
case class SomeRes[+A](value:List[A]) extends Res[A]
case object NonRes extends Res[Nothing]
case object SkipRes extends Res[Nothing]
object Main {
case class AbstractAction[A](run: Req => (A, Req))
implicit val monad = new Monad[AbstractAction] {
override def point[A](a: => A): AbstractAction[A] = AbstractAction(r => (a, r))
override def bind[A, B](fa: AbstractAction[A])(f: A => AbstractAction[B]): AbstractAction[B] = AbstractAction((r:Req) => {
val (a,r1) = fa.run(r)
f(a).run(r1)
})
}
type Action[A] = AbstractAction[Res[A]]
def first = AbstractAction{ (r: Req) =>
if (r.value.isEmpty) (NonRes, Req(" with 1 "))
else if (r.value == "skip") (SkipRes, Req(" with 1 "))
else (SomeRes(List("not empty req")), Req(" with 1 "))
}
def second = AbstractAction((r:Req) => (SomeRes(List("get req:"+r.value)), Req(r.value + " with 2 ")))
def three:Action[String] = for {
f <- first
s <- second
} yield {f <> s}
}
from scalaz.
It works, thx
By the way, it's that means I should use case class
instead of type
when I define something like Monad
?
from scalaz.
Related Issues (20)
- Scala 2.13 regression in EitherT instances (using 7.2.27) HOT 8
- Support LazyList for Scala 2.13 HOT 3
- scalaz.github.io is empty. There is no documentation. HOT 1
- Free, FreeAp and FreeT instances if Scala 2.13 or higher
- Publish for Scala.js 1.0-RC2 HOT 1
- Comparing Trees HOT 1
- release 7.3.0 final HOT 1
- scalafix rule for scalaz 7.2 => 7.3 HOT 1
- Apply instance/syntax for Function1 HOT 2
- Reducer instance in Apply makes function unserializable HOT 1
- Scaladoc generation failing on .liftM[OptionT] in scalaz 7.3.1
- Trouble with Apply on Kleisli HOT 4
- Running sequence with Free monad HOT 1
- libera.chat link does not work
- avoid `scala.App` in example
- ReactiveX operators for StreamT HOT 1
- Shall we remove the mandatory Trampoline from Cofree?
- Improving StreamT HOT 5
- Dequeues aren't amortized O(1) when using both `unsnoc` and `uncons` HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from scalaz.