Welcome! Got a question? Do you have -Ypartial-unification turned on? Other FAQs: http://typelevel.org/cats/faq.html
Hi there!
I'm trying to adapt Discipline's testing approach, but I'm experiencing issues with comparing values in effectful context F[_]
like IO[_]
.
The source of the problem is in discipline package in cats laws - there is an implicit converter from IsEq[A]
to Prop
, requiring an Eq[A]
and a prettifier A => Pretty
.
When A
is actually an IO[A]
, it means that to use Pretty
I have to reevaluate the effects I've already evaluated with Eq
or memoize them. I suppose I can come up with my own converter to Prop
which runs all effects and remembers their values at the beginning, but maybe I'm missing something and someone here can point me in the right direction.
PartialOrder also enables >, >=, <, and <= operators, but these are tricky to use because if you’re not careful you could end up using the built-in comparison operators.
http://eed3si9n.com/herding-cats/PartialOrder.html
ApplicativeError
raiseError[F[_]](e: E)
given ApplicativeError[F, E]
(new Exception : Throwable).raiseError[F, Int])
at which point F.raiseError(new Exception)
is more appealing
Hmm. I didn’t see any cases of that problem in my usage.
On a related note: if you’re wirting tests and you need an ApplicativeError
or MonadError
, do you just jump to using IO
(or, in my situation, StateT[IO, MyState, ?]
because I need MonadState
and MonadError
)? Or something less powerful than IO
? Try
?
Either
is a pretty easy one
Coyoneda
as well, so it's actually closer to Coyoneda
in haskell
a good way of looking at it is noting how Monad
can be expressed as either (forgetting Applicative
)
class Functor f => Monad f where
pure :: a -> f a
join :: f (f a) -> f a
or
class Monad f where
pure :: a -> f a
(>>=) :: f a -> (a -> f b) -> f b
.
The first definition gives rise to
data Free f a = Pure a | Roll (f (Free f a))
instance Functor f => Monad (Free f) where ...
and your algebra looks this way:
data Alg a = Put String a | Get String (String -> a)
instance Functor Alg where
The second definition, which is Operational
(and cats Free) gives rise to
data Free f a where
Pure :: a -> Free fa
FlatMap :: f a -> (a -> Free f b) -> Free f b
instance Monad (Free f a) -- note no Functor
and your algebra looks this way
data Alg a where
Put :: String -> Alg ()
Get :: String -> Alg String
and no Functor needed
Functor
for your algebra
class Functor f where
fmap :: (a -> b) -> f a -> f b
data Coyoneda f a where
Fmap :: (a -> b) -> f b -> Coyoneda f a
Free[Coyoneda[F, ?], A]
(with a FreeC
type synonym)
Operational
List
as the pattern functor
Free
(especially evident in the first version) is as a tree with a Functorful f
of children, and values at the leaves (the Pure
constructor is Leaf a
, and Roll
is the branch, with f
children). If you look at Cofree
, that's also a Tree with values at the branches instead, and again whose structure is determined by f
, and that's a Rose Tree
data Free f a = Leaf a | Node f (Free f a)
data Cofree f a = Node a (f (Cofree f a))
type Rose = Cofree []
-- replace and you get
data Rose a = Node a [Rose a]