Skip to content

Commit 2bf445f

Browse files
committed
Added liftR to functions as a workaround for Scala's poor type inference
You are currently cherry-picking commit 088ffad. Conflicts: HISTORY.md
1 parent c4a2c44 commit 2bf445f

File tree

5 files changed

+51
-6
lines changed

5 files changed

+51
-6
lines changed

HISTORY.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ History
33

44
### 0.5.3 (unreleased)
55

6+
* Workaround for Scala's type inference failing with `StateT.liftR` on functions.
7+
Instead of `f(_).liftR`, `f.liftR` is now available and is confirmed to work in `_runState`.
68

79
### 0.5.2 ([commit log](https://github.com/japgolly/scalajs-react/compare/v0.5.1...v0.5.2))
810

project/Build.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,10 @@ object ScalajsReact extends Build {
105105

106106
lazy val test = project
107107
.configure(commonSettings, publicationSettings, utestSettings)
108-
.dependsOn(core)
109-
.settings(name := "test")
108+
.dependsOn(core, scalaz71)
109+
.settings(
110+
name := "test",
111+
scalacOptions += "-language:reflectiveCalls")
110112

111113
// ==============================================================================================
112114
def scalazModule(name: String, version: String) = {

scalaz-7.0/src/main/scala/japgolly/scalajs/react/ScalazReact.scala

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,11 @@ object ScalazReact {
179179
ReactS lift s
180180
}
181181

182+
implicit final class SzRExt__StateTOps[I, M[+_], S, A](val f: I => StateT[M, S, A]) extends AnyVal {
183+
@inline def liftR(implicit M: Functor[M]): I => ReactST[M, S, A] =
184+
f(_).liftR
185+
}
186+
182187
implicit final class SzRExt_ReactSTOps[M[+_], S, A](val s: ReactST[M,S,A]) extends AnyVal {
183188
def addCallback(c: OpCallbackIO)(implicit M: Monad[M]): ReactST[M,S,A] =
184189
s.flatMap(ReactS.callbackT(c))
@@ -218,7 +223,7 @@ object ScalazReact {
218223
def runStateS[M[+_], A](st: => StateT[M, S, A])(implicit C: CC, M: M ~> IO, N: Functor[M]): IO[A] =
219224
runState(st.liftR)
220225

221-
@deprecated("Instead of _runStateS(i ⇒ s | f), use _runState(i ⇒ s.liftR | f(_).liftR). _runStateS will be removed in 0.7.0.", "0.5.2")
226+
@deprecated("Instead of _runStateS(f), use _runState(f.liftR). _runStateS will be removed in 0.7.0.", "0.5.2")
222227
def _runStateS[I, M[+_], A](f: I => StateT[M, S, A])(implicit C: CC, M: M ~> IO, N: Functor[M]): I => IO[A] =
223228
_runState(f(_).liftR)
224229

@@ -235,7 +240,7 @@ object ScalazReact {
235240
def runStateFS[M[+_], A](st: => StateT[M, S, A])(implicit C: CC, M: M ~> IO, N: Functor[M], F: ChangeFilter[S]): IO[A] =
236241
runStateF(st.liftR)
237242

238-
@deprecated("Instead of _runStateFS(i ⇒ s | f), use _runStateF(i ⇒ s.liftR | f(_).liftR). _runStateFS will be removed in 0.7.0.", "0.5.2")
243+
@deprecated("Instead of _runStateFS(f), use _runStateF(f.liftR). _runStateFS will be removed in 0.7.0.", "0.5.2")
239244
def _runStateFS[I, M[+_], A](f: I => StateT[M, S, A])(implicit C: CC, M: M ~> IO, N: Functor[M], F: ChangeFilter[S]): I => IO[A] =
240245
_runStateF(f(_).liftR)
241246
}

scalaz-7.1/src/main/scala/japgolly/scalajs/react/ScalazReact.scala

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,11 @@ object ScalazReact {
178178
ReactS lift s
179179
}
180180

181+
implicit final class SzRExt__StateTOps[I, M[_], S, A](val f: I => StateT[M, S, A]) extends AnyVal {
182+
@inline def liftR(implicit M: Functor[M]): I => ReactST[M, S, A] =
183+
f(_).liftR
184+
}
185+
181186
implicit final class SzRExt_ReactSTOps[M[_], S, A](val s: ReactST[M,S,A]) extends AnyVal {
182187
def addCallback(c: OpCallbackIO)(implicit M: Monad[M]): ReactST[M,S,A] =
183188
s.flatMap(ReactS.callbackT(c))
@@ -217,7 +222,7 @@ object ScalazReact {
217222
def runStateS[M[_], A](st: => StateT[M, S, A])(implicit C: CC, M: M ~> IO, N: Functor[M]): IO[A] =
218223
runState(st.liftR)
219224

220-
@deprecated("Instead of _runStateS(i ⇒ s | f), use _runState(i ⇒ s.liftR | f(_).liftR). _runStateS will be removed in 0.7.0.", "0.5.2")
225+
@deprecated("Instead of _runStateS(f), use _runState(f.liftR). _runStateS will be removed in 0.7.0.", "0.5.2")
221226
def _runStateS[I, M[_], A](f: I => StateT[M, S, A])(implicit C: CC, M: M ~> IO, N: Functor[M]): I => IO[A] =
222227
_runState(f(_).liftR)
223228

@@ -234,7 +239,7 @@ object ScalazReact {
234239
def runStateFS[M[_], A](st: => StateT[M, S, A])(implicit C: CC, M: M ~> IO, N: Functor[M], F: ChangeFilter[S]): IO[A] =
235240
runStateF(st.liftR)
236241

237-
@deprecated("Instead of _runStateFS(i ⇒ s | f), use _runStateF(i ⇒ s.liftR | f(_).liftR). _runStateFS will be removed in 0.7.0.", "0.5.2")
242+
@deprecated("Instead of _runStateFS(f), use _runStateF(f.liftR). _runStateFS will be removed in 0.7.0.", "0.5.2")
238243
def _runStateFS[I, M[_], A](f: I => StateT[M, S, A])(implicit C: CC, M: M ~> IO, N: Functor[M], F: ChangeFilter[S]): I => IO[A] =
239244
_runStateF(f(_).liftR)
240245
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package japgolly.scalajs.react
2+
3+
import utest._
4+
import scalaz.{~>, StateT, Monad}
5+
import scalaz.effect.IO
6+
import ScalazReact._
7+
8+
/**
9+
* Scala's type inference can be pretty weak sometimes.
10+
* Successful compilation will suffice as proof for most of these tests.
11+
*/
12+
object ScalazTest extends TestSuite {
13+
14+
def test[A] = new {
15+
def apply[B](f: A => B) = new {
16+
def expect[C](implicit ev: B =:= C): Unit = ()
17+
}
18+
}
19+
20+
trait M[A]
21+
implicit val mMonad = null.asInstanceOf[Monad[M] with (M ~> IO)]
22+
trait S
23+
trait A
24+
trait B
25+
val c = null.asInstanceOf[ComponentScopeM[Unit, S, Unit]]
26+
27+
val tests = TestSuite {
28+
"runState(StateT.liftR)" - test[StateT[M,S,A] ](s => c.runState(s.liftR) ).expect[IO[A]]
29+
"_runState((I→StateT).liftR)" - test[B => StateT[M,S,A]](s => c._runState(s.liftR)).expect[B => IO[A]]
30+
}
31+
}

0 commit comments

Comments
 (0)