frees-io / iota Goto Github PK
View Code? Open in Web Editor NEWFast [co]product types with a clean syntax. For Cats & Scalaz.
License: Apache License 2.0
Fast [co]product types with a clean syntax. For Cats & Scalaz.
License: Apache License 2.0
It would be good to have an accessor for products and coproducts.
Even better if there was a way to get a tuple / nested scalaz disjunction.
And for products, even better if there was a macro that allowed me to pass a Prod
to a method that accepts X parameters ๐
The core of Iota depends on Cats/Scalaz and requires some nasty tricks to get cross compilation to work. I'd like build out my own FP layer for internal use only so that the internal implementation is simplified.
Initially, the external modules would stay the same: there'd be no binary changes for the public API. We'd still conditionally build a iota
for Cats and iotaz
for Scalaz. I'd target this for v0.5.0
.
A second (optional) step would be to remove the conditional building and just have a an iota
module with a iota-cats
and iota-scalaz
extension modules. This is pretty easy to do once the iota internals are self supporting. A decision on is needed before I'd consider a v1.0.0
release.
cc @raulraja @peterneyens @fommil any thoughts?
Actual version: 0.6.20
Patch: 0.6.22
Minor: -
Major: -
It would be nice to have compilation error if there is a pattern matching on not all injected values.
e.g.
type Primitive = Cop[String :: Boolean :: TNil
object Primitive {
val Str= Cop.Inject[String, Primitive]
val Bool= Cop.Inject[Boolean, Primitive]
}
def print(v: Primitive) =
v match {
case Str(v) => println(v)
}
should throw compilation error since there is not Bool case
Actual version: 2.1.0
Patch: 2.1.1
Minor: -
Major: -
Actual version: 1.19
Patch: -
Minor: 1.20
Major: -
The large TList/TListK tests cause StackOverflow exceptions in the Scalaz version of Iota. Investigate how to minimize the stack depth per recursion step of hylo.
this would be very useful... e.g. to build a Foldable1 from such things.
Actual version: 0.6.20
Patch: 0.6.22
Minor: -
Major: -
Some ideas:
Use the lowercase greek iota character?
Maybe a variation of the 3D freestyle logo?
We should upgrade to sbt-freestyle
0.2.1 (addSbtPlugin("io.frees" % "sbt-freestyle" % "0.2.1")
) and ports iota
to sbt 1.0.1.
There is a WIP https://github.com/frees-io/iota/tree/port-to-sbt-1.0.x, blocked because AutoTLSPlugin
it's tied to sbt 0.13.
Actual version: 0.6.20
Patch: 0.6.22
Minor: -
Major: -
Actual version: 8.1.16.v20140903
Patch: 8.1.22.v20160922
Minor: 8.2.0.v20160908
Major: -
typelevel/cats#1642 will allow direct compatibility with InjectK
.
I am trying out iota for scalaz, but getting compilation errors.
To reproduce:
iotaz._
instead of iota._
in tut/README.md
(as indicated in the README)sbt
: readme/tut
Details:
iota (master)$ git diff modules
diff --git a/modules/readme/src/main/tut/README.md b/modules/readme/src/main/tut/README.md
index 0cec909..2f9c682 100644
--- a/modules/readme/src/main/tut/README.md
+++ b/modules/readme/src/main/tut/README.md
@@ -32,7 +32,7 @@ constant time access of the values. This syntax scales cleanly to
support any number of disjunct types.
```tut:silent
-import iota._ // or iotaz._
+import iotaz._ // or iotaz._
import TList.::
import TListK.:::
@@ -229,4 +229,4 @@ Copyright (C) 2016-2017 47 Degrees. <http://47deg.com>
[comment]: # (End Copyright)
-[free example]: modules/tests/src/test/scala/iotatests/FreeCopKTests.scala
\ No newline at end of file
+[free example]: modules/tests/src/test/scala/iotatests/FreeCopKTests.scala
sbt:iota> readme/tut
[info] Running tut.TutMain /Users/rintcius/dev/iota/modules/readme/src/main/tut /Users/rintcius/dev/iota .*\.(md|markdown|txt|htm|html)
[tut] compiling: /Users/rintcius/dev/iota/modules/readme/src/main/tut/README.md
[tut] *** Error reported at /Users/rintcius/dev/iota/modules/readme/src/main/tut/README.md:98
<console>:25: error: value IntFoo is not a case class, nor does it have an unapply/unapplySeq member
case IntFoo(int) => s"int: $int"
^
<console>:26: error: value StringFoo is not a case class, nor does it have an unapply/unapplySeq member
case StringFoo(string) => s"string: $string"
^
<console>:27: error: value DoubleFoo is not a case class, nor does it have an unapply/unapplySeq member
case DoubleFoo(double) => s"double: $double"
^
[error] (run-main-2) tut.TutException: Tut execution failed.
[error] tut.TutException: Tut execution failed.
[error] at tut.TutMain$.$anonfun$runl$6(TutMain.scala:17)
[error] at tut.Zed$State.$anonfun$flatMap$1(Zed.scala:32)
[error] at tut.Zed$State.$anonfun$flatMap$1(Zed.scala:32)
[error] at tut.Zed$IOOps.unsafePerformIO(Zed.scala:99)
[error] at tut.TutMain$.main(TutMain.scala:8)
[error] at tut.TutMain.main(TutMain.scala)
[error] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[error] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[error] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[error] at java.lang.reflect.Method.invoke(Method.java:498)
[error] at sbt.Run.invokeMain(Run.scala:89)
[error] at sbt.Run.run0(Run.scala:83)
[error] at sbt.Run.execute$1(Run.scala:61)
[error] at sbt.Run.$anonfun$run$4(Run.scala:73)
[error] at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
[error] at sbt.util.InterfaceUtil$$anon$1.get(InterfaceUtil.scala:10)
[error] at sbt.TrapExit$App.run(TrapExit.scala:252)
[error] at java.lang.Thread.run(Thread.java:748)
[error] java.lang.RuntimeException: Nonzero exit code: 1
[error] at scala.sys.package$.error(package.scala:27)
[error] at tut.TutPlugin$.$anonfun$tutOne$1(TutPlugin.scala:149)
[error] at scala.util.Success.foreach(Try.scala:249)
[error] at tut.TutPlugin$.tutOne(TutPlugin.scala:149)
[error] at tut.TutPlugin$.$anonfun$projectSettings$19(TutPlugin.scala:72)
[error] at scala.Function1.$anonfun$compose$1(Function1.scala:44)
[error] at sbt.internal.util.$tilde$greater.$anonfun$$u2219$1(TypeFunctions.scala:42)
[error] at sbt.std.Transform$$anon$4.work(System.scala:64)
[error] at sbt.Execute.$anonfun$submit$2(Execute.scala:257)
[error] at sbt.internal.util.ErrorHandling$.wideConvert(ErrorHandling.scala:16)
[error] at sbt.Execute.work(Execute.scala:266)
[error] at sbt.Execute.$anonfun$submit$1(Execute.scala:257)
[error] at sbt.ConcurrentRestrictions$$anon$4.$anonfun$submitValid$1(ConcurrentRestrictions.scala:167)
[error] at sbt.CompletionService$$anon$2.call(CompletionService.scala:32)
[error] at java.util.concurrent.FutureTask.run(FutureTask.java:266)
[error] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
[error] at java.util.concurrent.FutureTask.run(FutureTask.java:266)
[error] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
[error] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
[error] at java.lang.Thread.run(Thread.java:748)
Per conversation at https://gitter.im/47deg/freestyle?at=59ff9f01976e63937e2f9405 there is some useful type level computation we can perform over Cop
and CopK
to fold two different Coproduct's and apply Ops while folding.
Actual version: 0.6.20
Patch: 0.6.22
Minor: -
Major: -
The examples module is currently for cats only. A new examples module should be added for the scalaz version of iota. The cats examples can be ported to Scalaz, and new Scalaz specific examples can be added.
Note:
Most of the core code is using the "yax" trick to cross compile. This causes the code to be somewhat convoluted. This is less ideal for example code, which should be as clean as possible. This is why it's preferable to have two separate example modules tailored for each underlying lib, instead of one combined one.
Things to do:
Actual version: 8.1.16.v20140903
Patch: 8.1.22.v20160922
Minor: 8.2.0.v20160908
Major: -
It would be nice if iota would compile to scala-native as well.
Actual version: 0.9.3
Patch: 0.9.4
Minor: -
Major: -
Actual version: 0.6.20
Patch: 0.6.22
Minor: -
Major: -
Actual version: 8.1.16.v20140903
Patch: 8.1.22.v20160922
Minor: 8.2.0.v20160908
Major: 9.4.8.v20171121
Actual version: 0.9.4
Patch: 0.9.6
Minor: -
Major: -
The following file is derived from Matryoshka: https://github.com/47deg/iota/blob/6f245e5df0927f7e541fb0be5e545253a05bee05/modules/core/src/main/scala/iota/internal/catryoshka.scala
Attribution is made and the original source is under the same license as Iota. However, I'm not sure if it's done correctly as Matryoshka's licensing/copying information is a bit spread out.
like in shapeless it would be great to have a way of automatically going to and from a Prod for case classes and case objects, and to/from Cop for sealed traits.
In addition, it would be great to have specialised equivalents for tuples and scalaz disjunctions.
unzip -l ~/.coursier/cache/v1/https/repo1.maven.org/maven2/io/frees/iotaz-core_2.12/0.3.2/iotaz-core_2.12-0.3.2-javadoc.jar
Archive: /home/fommil/.coursier/cache/v1/https/repo1.maven.org/maven2/io/frees/iotaz-core_2.12/0.3.2/iotaz-core_2.12-0.3.2-javadoc.jar
End-of-central-directory signature not found. Either this file is not
a zipfile, or it constitutes one disk of a multi-part archive. In the
latter case the central directory and zipfile comment will be found on
the last disk(s) of this archive.
unzip: cannot find zipfile directory in one of /home/fommil/.coursier/cache/v1/https/repo1.maven.org/maven2/io/frees/iotaz-core_2.12/0.3.2/iotaz-core_2.12-0.3.2-javadoc.jar or
/home/fommil/.coursier/cache/v1/https/repo1.maven.org/maven2/io/frees/iotaz-core_2.12/0.3.2/iotaz-core_2.12-0.3.2-javadoc.jar.zip, and cannot find /home/fommil/.coursier/cache/v1/https/repo1.maven.org/maven2/io/frees/iotaz-core_2.12/0.3.2/iotaz-core_2.12-0.3.2-javadoc.jar.ZIP, period.
this breaks tooling, e.g. ensime.
it would be good to be able to zip together products, getting back a product of tuples
and it would be good to be able to zip a product with a coproduct, getting back a coproduct.
and zipping coproducts ... but I'm not sure what that would give back. possibly a Maybe
of tuple?
See #24
I think we are safe already as we are calling .asType.toType
on the symbol from TypeRef
s after typechecking. But I'm not sure, so I have followed up by asking on the scala/contributors gitter. "Worst" case I will add guard statements to the existing code and have helpers return NoType
when the conversion can't be performed.
alluded to in #84
object LazyProd {
def apply[A1](a1: => A1): Prod[Name[A1] :: TNil] = Prod(Name(a1))
def apply[A1, A2](a1: => A1, a2: => A2): Prod[Name[A1] :: Name[A2] :: TNil] =
Prod(Name(a1), Name(a2))
def apply[A1, A2, A3](
a1: => A1,
a2: => A2,
a3: => A3
): Prod[Name[A1] :: Name[A2] :: Name[A3] :: TNil] =
Prod(Name(a1), Name(a2), Name(a3))
def apply[A1, A2, A3, A4](
a1: => A1,
a2: => A2,
a3: => A3,
a4: => A4
): Prod[Name[A1] :: Name[A2] :: Name[A3] :: Name[A4] :: TNil] =
Prod(Name(a1), Name(a2), Name(a3), Name(a4))
}
object Huns {
val empty: Prod[TNil] = Prod()
def from2T[A1, A2](e: (A1, A2)): Prod[A1 :: A2 :: TNil] =
Prod.unsafeApply(List(e._1, e._2))
def from3T[A1, A2, A3](e: (A1, A2, A3)): Prod[A1 :: A2 :: A3 :: TNil] =
Prod.unsafeApply(List(e._1, e._2, e._3))
def from4T[A1, A2, A3, A4](
e: (A1, A2, A3, A4)
): Prod[A1 :: A2 :: A3 :: A4 :: TNil] =
Prod.unsafeApply(List(e._1, e._2, e._3, e._4))
def from1[A1](a1: A1): Prod[A1 :: TNil] = Prod.unsafeApply(List(a1))
def from2[A1, A2](a1: A1, a2: A2): Prod[A1 :: A2 :: TNil] =
Prod.unsafeApply(List(a1, a2))
def from3[A1, A2, A3](a1: A1, a2: A2, a3: A3): Prod[A1 :: A2 :: A3 :: TNil] =
Prod.unsafeApply(List(a1, a2, a3))
def from3[A1, A2, A3, A4](a1: A1,
a2: A2,
a3: A3,
a4: A4): Prod[A1 :: A2 :: A3 :: A4 :: TNil] =
Prod.unsafeApply(List(a1, a2, a3, a4))
def to1T[A1](a: Prod[A1 :: TNil]): A1 = a.values(0).asInstanceOf[A1]
def to2T[A1, A2](a: Prod[A1 :: A2 :: TNil]): (A1, A2) = (
a.values(0).asInstanceOf[A1],
a.values(1).asInstanceOf[A2]
)
def to3T[A1, A2, A3](a: Prod[A1 :: A2 :: A3 :: TNil]): (A1, A2, A3) = (
a.values(0).asInstanceOf[A1],
a.values(1).asInstanceOf[A2],
a.values(2).asInstanceOf[A3]
)
def to4T[A1, A2, A3, A4](
a: Prod[A1 :: A2 :: A3 :: A4 :: TNil]
): (A1, A2, A3, A4) = (
a.values(0).asInstanceOf[A1],
a.values(1).asInstanceOf[A2],
a.values(2).asInstanceOf[A3],
a.values(3).asInstanceOf[A4]
)
}
object Catholics {
def from1[A1](e: A1): Cop[A1 :: TNil] = Cop.unsafeApply(0, e)
def from2[A1, A2](e: A1 \/ A2): Cop[A1 :: A2 :: TNil] = e match {
case -\/(a) => Cop.unsafeApply(0, a)
case \/-(b) => Cop.unsafeApply(1, b)
}
def from3[A1, A2, A3](e: A1 \/ (A2 \/ A3)): Cop[A1 :: A2 :: A3 :: TNil] =
e match {
case -\/(a) => Cop.unsafeApply(0, a)
case \/-(-\/(b)) => Cop.unsafeApply(1, b)
case \/-(\/-(c)) => Cop.unsafeApply(2, c)
}
def from4[A1, A2, A3, A4](
e: A1 \/ (A2 \/ (A3 \/ A4))
): Cop[A1 :: A2 :: A3 :: A4 :: TNil] =
e match {
case -\/(a) => Cop.unsafeApply(0, a)
case \/-(-\/(b)) => Cop.unsafeApply(1, b)
case \/-(\/-(-\/(c))) => Cop.unsafeApply(2, c)
case \/-(\/-(\/-(d))) => Cop.unsafeApply(3, d)
}
def to1[A1](c: Cop[A1 :: TNil]): A1 = c.value.asInstanceOf[A1]
def to2[A1, A2](c: Cop[A1 :: A2 :: TNil]): A1 \/ A2 = c.index match {
case 0 => -\/(c.value.asInstanceOf[A1])
case 1 => \/-(c.value.asInstanceOf[A2])
}
def to3[A1, A2, A3](c: Cop[A1 :: A2 :: A3 :: TNil]): A1 \/ (A2 \/ A3) =
c.index match {
case 0 => -\/(c.value.asInstanceOf[A1])
case 1 => \/-(-\/(c.value.asInstanceOf[A2]))
case 2 => \/-(\/-(c.value.asInstanceOf[A3]))
}
def to4[A1, A2, A3, A4](
c: Cop[A1 :: A2 :: A3 :: A4 :: TNil]
): A1 \/ (A2 \/ (A3 \/ A4)) = c.index match {
case 0 => -\/(c.value.asInstanceOf[A1])
case 1 => \/-(-\/(c.value.asInstanceOf[A2]))
case 2 => \/-(\/-(-\/(c.value.asInstanceOf[A3])))
case 3 => \/-(\/-(\/-(c.value.asInstanceOf[A4])))
}
}
Actual version: 2.1.0
Patch: 2.1.1
Minor: -
Major: -
Actual version: 8.1.16.v20140903
Patch: 8.1.22.v20160922
Minor: 8.2.0.v20160908
Major: 9.4.8.v20171121
The order of parameters to type list operations is counter intuitive and should be switched.
Consider
def apply[L <: TList, LF <: TList](a: Cop[L])(fs: Prod[LF])(
implicit ev: TList.Compute.Aux[Op.Map[? => B, L], LF]
): B =
fs.values(a.index).asInstanceOf[Any => B].apply(a.value)
This would be more clearly expressed as
def apply[L <: TList, LF <: TList](a: Cop[L])(fs: Prod[LF])(
implicit ev: TList.Compute.Aux[Op.Map[LF, ? => B, L]]
): B =
fs.values(a.index).asInstanceOf[Any => B].apply(a.value)
Actual version: 7.2.15
Patch: 7.2.19
Minor: -
Major: -
I am trying to bundle an app that depends on freestyle as a single jar using sbt-assembly and i am getting conflicts about duplicate classes from scala-library. The issue seems to come from iota which shows this dependency tree including both versions of the scala-library (the tree is generated using https://github.com/jrudolph/sbt-dependency-graph):
[info] io.frees:freestyle_2.12:0.2.1-SNAPSHOT [S]
[info] +-com.47deg:iota-core_2.12:0.2.0
[info] | +-org.typelevel:cats-core_2.12:0.9.0
[info] | | +-com.github.mpilquist:simulacrum_2.12:0.10.0
[info] | | | +-org.scala-lang:scala-library:2.12.2
[info] | | | +-org.typelevel:macro-compat_2.12:1.1.1
[info] | | | +-org.scala-lang:scala-library:2.12.2
...
[info] | +-org.typelevel:scala-library:2.12.1
...
I have searched this repo and the only reference to typelevel seems to be in the scalaOrganization at file https://github.com/47deg/iota/blob/master/project/ProjectPlugin.scala which may also explain why i am getting org.scala-lang:scala-library in version 2.12.2 and org.typelevel:scala-library in version 2.12.1. It seems that the scalaOrganization defined as typelevel or some other sbt configuration may be causing the problem. Ideally since most projects will already include org.scala-lang:scala-library anyway it may be better if no dependency on the typelevel version existed although i am not sure about the implications of this.
With the potential inclusion of QList
and CopQ
, we will have:
Cop
CopK
CopQ
TList
KList
QList
What about refactoring this into to:
Cop
CopK
CopQ
TList
TListK
TListQ
This simplifies names, IMHO, because the suffix always indicate the kindness. This is in alignment with other libs like cats.
Actual version: 0.6.20
Patch: 0.6.22
Minor: -
Major: -
I need to be able to do something like this (aka, apply a natural transformation to a product):
def map[A[_], B[_], AS <: TListK, BS <: TListK](
as: Prod[AS]
)(f: A ~> B)(
implicit ev: TListK.Compute.Aux[TListK.Op.Map[B, BS], AS]
): Prod[BS] = {
Prod.unsafeApply(as.values.asInstanceOf[Seq[A[scala.Any]]].map(f))
}
but there doesn't seem to be any way to do it.
This (or a workaround) is sadly blocking my ability to complete scalaz-deriving
's support for covariant typeclass derivation: https://gitlab.com/fommil/scalaz-deriving/merge_requests/86
Currently, iota is not using sbt-freestyle, it should since now it's a part of frees-io
organization.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.