-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Add Decidable
#2607
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Add Decidable
#2607
Changes from all commits
289c2fb
ab2105f
b290417
8ebe564
4ae9ba0
6ceae06
764b8ca
04b1433
57abb07
ad4c062
244e7a5
a8f8079
164bc81
a14d7c4
0a6fbf5
b310dba
5b5f04b
79f96a8
45fe0c4
f3ce9ec
2d38c82
26d812d
ce3f380
289588a
f9d8f18
ec6920b
4af7db2
8a99300
a27b391
39e6395
d94ad94
7e357aa
12ef1f9
af15b3c
ea48c08
a0325e8
c8ff7b8
55bdd91
692c3e0
85d29ef
beb03d6
dccb090
d88f178
d67ee5c
2ebeb45
b64f3f8
45966c3
91962c4
72289b1
87fe236
3d96d06
8ab26f1
9edb1e4
ffe0459
8bcaa2e
da8224a
b051a4d
c787ae8
13570c7
7cc84b7
fef5ff0
011c8eb
7066dbd
cb51073
92dfde7
2844752
0e3ebe8
3a0b2c4
7730deb
68c27f2
4814ed5
3daa7e1
587f274
73033a1
6e75fba
ebf2acf
bf5e352
8d61434
bcf4801
5274449
e06a780
0938926
9620658
019ebf7
a9e56b9
a60cadd
00a6cd9
3ef22ed
0c9c090
70f42df
d5be88a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| /* | ||
| * Copyright (c) 2015 Typelevel | ||
| * | ||
| * Permission is hereby granted, free of charge, to any person obtaining a copy of | ||
| * this software and associated documentation files (the "Software"), to deal in | ||
| * the Software without restriction, including without limitation the rights to | ||
| * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of | ||
| * the Software, and to permit persons to whom the Software is furnished to do so, | ||
| * subject to the following conditions: | ||
| * | ||
| * The above copyright notice and this permission notice shall be included in all | ||
| * copies or substantial portions of the Software. | ||
| * | ||
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS | ||
| * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | ||
| * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER | ||
| * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| */ | ||
|
|
||
| package cats | ||
|
|
||
| /** | ||
| * [[Decidable]] functors are functors that supply | ||
| * a `decide` operation allowing choices to be made. | ||
| * | ||
| * This is comparable to [[Alternative]] in the | ||
| * covariant case. | ||
| * | ||
| * Must obey laws in `cats.laws.DecidableLaws`. | ||
| * | ||
| * Based on ekmett's contravariant library: | ||
| * [[https://hackage.haskell.org/package/contravariant-1.4/docs/Data-Functor-Contravariant-Divisible.html#g:2]] | ||
| */ | ||
| trait Decidable[F[_]] extends ContravariantMonoidal[F] { | ||
| def sum[A, B](fa: F[A], fb: F[B]): F[Either[A, B]] | ||
| def zero: F[Nothing] | ||
|
|
||
| def decide[A, B, C](fa: F[A], fb: F[B])(f: C => Either[A, B]): F[C] = | ||
| contramap(sum(fa, fb))(f) | ||
|
|
||
| def lose[A](f: A => Nothing): F[A] = contramap[Nothing, A](zero)(f) | ||
| } | ||
|
Comment on lines
+36
to
+44
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok I realize this is a bit late in the day, but wouldn't it make more sense to define it like this? Basically trade two abstract defs ( // abstract
def decide[A, B, C](fa: F[A], fb: F[B])(f: C => Either[A, B]): F[C]
// concrete
def contramap[A, B](fa: F[A])(f: B => A): F[B] =
decide(fa, zero)(b => Left(f(b)))
def sum[A, B](fa: F[A], fb: F[B]): F[Either[A, B]] =
decide(fa, fb)(identity)
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Based on principle of power, I suspect that this similar adjustment should also be made. // abstract
def lose[A](f: A => Nothing): F[A]
// concrete
def zero: F[Nothing] = lose(identity)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm fine with this! I think this actually better fits our current modeling with a monoidal / semigroupal hierarchy. This encoding I think predates some of the rest of that work and was originally part of that push. |
||
|
|
||
| object Decidable { | ||
|
|
||
| /** | ||
| * Summon an instance of [[Decidable]] for `F`. | ||
| */ | ||
| @inline def apply[F[_]](implicit instance: Decidable[F]): Decidable[F] = instance | ||
|
|
||
| trait Ops[F[_], A] extends Serializable { | ||
| type TypeClassType <: Decidable[F] | ||
| def self: F[A] | ||
| val typeClassInstance: TypeClassType | ||
| def sum[B](fb: F[B]): F[Either[A, B]] = typeClassInstance.sum[A, B](self, fb) | ||
| def decide[B, C](fb: F[B])(f: C => Either[A, B]): F[C] = typeClassInstance.decide[A, B, C](self, fb)(f) | ||
| } | ||
| trait AllOps[F[_], A] extends Ops[F, A] with ContravariantMonoidal.AllOps[F, A] { | ||
| type TypeClassType <: Decidable[F] | ||
| } | ||
| trait ToDecidableOps extends Serializable { | ||
| implicit def toDecidableOps[F[_], A](target: F[A])(implicit tc: Decidable[F]): Ops[F, A] { | ||
| type TypeClassType = Decidable[F] | ||
| } = | ||
| new Ops[F, A] { | ||
| type TypeClassType = Decidable[F] | ||
| val self: F[A] = target | ||
| val typeClassInstance: TypeClassType = tc | ||
| } | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.