-
-
Save missingfaktor/2266798 to your computer and use it in GitHub Desktop.
scala> trait TF { | |
| type ![A] | |
| } | |
defined trait TF | |
scala> type Curried2[F[_, _]] = TF { | |
| type ![X] = TF { | |
| type ![Y] = F[X, Y] | |
| } | |
| } | |
defined type alias Curried2 | |
scala> "a".pure[Curried2[State] # ![Int] # !] | |
res0: scalaz.State[Int,java.lang.String] = scalaz.States$$anon$1@6e375e |
@mergeconflict: Oh yes, TF
isn't necessary. Thanks!
Could even go further:
scala> type ![F[_, _], A] = { type ![B] = F[A, B] }
defined type alias $bang
scala> "a".pure[(State ! Int) # !]
res0: scalaz.State[Int,java.lang.String] = scalaz.States$$anon$1@6e375e
... but I'm not sure I prefer this to my idea.
I wouldn't use this one because when scaled up, the syntax won't look the same for higher arities. The approach proposed in the original gist does not have this problem.
I am not sure what your proposed solution (on marakana post) buys. You are still using type lambda there. The value level equivalents would be:
g(x => foo(bar(x)))
changed to val f = x => foo(bar(x)); g(f)
True, the (State ! Int) # !
thing is just an idea I had for an arity-2 shortcut. Yours is definitely more general.
My solution does still have the type lambda in there; the only thing I'm doing is giving it an interesting name within the scope it applies to. I think our ideas both complement each other... We could have:
def stateMonad[S] = {
type `State[S]` = Curried2[State] # ![S] # !
new Monad[`State[S]`] { ... }
}
By the way, somebody's probably pointed this out before but couldn't there be some nice symmetry between infix/postfix notation for values (omitting dots) and for types (omitting hashes):
x.foo(a).bar <--> X#Foo[A]#Bar
x foo a bar <--> X Foo A Bar ???
That would make your Curried2
thing neater: Curried2[State] ! S !
Yes, the complement-version indeed looks nicer.
As for A B C
syntax, it already means B[A, C]
.
D'oh, of course.
Okay, how about this craziness:
scala> type ![F <: { type !![_] }, A] = F # !![A]
defined type alias $bang
scala> type Curried2[F[_, _]] = {
| type !![A] = {
| type !![B] = F[A, B]
| }
| }
defined type alias Curried2
scala> type LookNoHashes[A] = Curried2[State] ! Int ! A
defined type alias LookNoHashes
:)
I can't say I wasn't anticipating this. ;-)
Note: I'm a moron.
def stateMonad[S] = {
type `State[S]`[A] = State[S, A]
new Monad[`State[S]`] { ... }
}
Duh... No need for the type lambda trick here at all. Or rather, since we have our enclosing scope with S
defined, we're sort of "inside" the type lambda already.
For us both: http://alltheragefaces.com/img/faces/large/misc-genius-l.png. :-D
Interesting... How about just: