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
Improve doc for Func #2650
Comments
Eugene goes into the rationale in herding-cats, day 11. |
I am still trying to understand the mechanics of the @eed3si9n in herding-cats, day 11 shows two benefits of
If I am not mistaken, neither of these make use of the Below |
Here's sudoku solved using Func - http://eed3si9n.com/sudoku-using-func |
Why can't one use Can't all |
Here's from herding cats, day 11:
Using scala> val f = Func.appFunc { x: Int => List(x.toString + "!") }
f: cats.data.AppFunc[List,Int,String] = cats.data.Func$$anon$6@a6b56dd
scala> val g = Func.appFunc { x: Int => (Some(x.toString + "?"): Option[String]) }
g: cats.data.AppFunc[Option,Int,String] = cats.data.Func$$anon$6@2d0f032f
scala> val h = f product g
h: cats.data.AppFunc[[α]cats.data.Tuple2K[List,Option,α],Int,String] = cats.data.Func$$anon$6@625084a0 The types gets more messy if we compose multiple levels. See word count. scala> type Count[A] = Const[Int, A]
scala> val countChar: AppFunc[Count, Char, Unit] = ...
scala> val countLine: AppFunc[Count, Char, Unit] = ...
scala> val countWord =
| appFunc { (c: Char) =>
| for {
| x <- get[Boolean]
| y = !isSpace(c)
| _ <- set(y)
| } yield testIf(y && !x)
| }.andThen(appFunc(liftInt))
countWord: cats.data.AppFunc[[γ$3$]cats.data.Nested[[A]cats.data.IndexedStateT[cats.Eval,Boolean,Boolean,A],Count,γ$3$],Char,Unit] = cats.data.Func$$anon$6@5b1c2405
scala> val countAll = countWord.product(countLine).product(countChar)
countAll: cats.data.AppFunc[[α]cats.data.Tuple2K[[α]cats.data.Tuple2K[[γ$3$]cats.data.Nested[[A]cats.data.IndexedStateT[cats.Eval,Boolean,Boolean,A],Count,γ$3$],Count,α],Count,α],Char,Unit] = cats.data.Func$$anon$6@3cb9532f At the end of the day the return type is still in the form of |
As an experiment, I made def product[G[_]](g: Kleisli[G, A, B]): Kleisli[λ[α => Tuple2K[F, G, α]], A, B] = {
Kleisli[λ[α => Tuple2K[F, G, α]], A, B] { a: A =>
Tuple2K(self.run(a), g.run(a))
}
}
def composeNested[G[_], C](g: Kleisli[G, C, A])(implicit G: Functor[G]): Kleisli[Nested[G, F, ?], C, B] = {
Kleisli[Nested[G, F, ?], C, B]({ c: C =>
Nested(G.map(g.run(c))(self.run))
})
}
def andThenNested[G[_], C](g: Kleisli[G, B, C])(implicit F: Functor[F]): Kleisli[Nested[F, G, ?], A, C] =
g.composeNested(self) So, summing up:
Does this justify the addition of https://github.com/typelevel/cats/compare/master...kamilkloch:func-2650?expand=1 |
Doesn't the name Kleisli come from Kleisli arrow in the Kleisli category The applicative function composition needs strictly weaker constraint, and it's more powerful because we are talking about typelevel |
This seems interesting, I'll try to write the docspage, though it might take me a while |
Nobody knows what the hell
Func
does ... linking to a 25-page Haskell paper (even a good one) isn't ideal. Can we improve the doc, at least to the point of explaining why we need bothFunc
andKleisli
and how you might use it?There is some discussion here.
The text was updated successfully, but these errors were encountered: