class Fn1Arrow extends Arrow[Function1] {
def arr[B,C](f: B => C): B => C =
f
def >>>[B,C,D](f: B => C, g: C => D): B => D =
=> g(f(b))
b
def first[B,C,D](f: B => C): ((B,D)) => (C,D) =
=> (f(bd._1), bd._2)
bd
def second[B,C,D](f: B => C): ((D,B)) => (D,C) =
=> first(f)(db.swap).swap
db
def ***[B,C,D,E](f: B => C, g: D => E): ((B,D)) => (C,E) =
=> (f(bd._1), g(bd._2))
bd
def &&&[B,C,D](f: B => C, g: B => D): B => (C,D) =
=> ***(f, g)((b,b))
b
}
class InfixFn1Arrow[B,C](f: B => C) {
def arr =
f
def >>>[D](g: C => D) =
(b: B) => g(f(b))
def first[D](bd: (B,D)) =
(f(bd._1), bd._2)
def second[D](db: (D,B)) =
first(db.swap).swap
def ***[D,E](g: D => E) =
(bd: (B,D)) => (f(bd._1), g(bd._2))
def &&&[D](g: B => D) =
(b: B) => ***(g)((b,b))
}
implicit def function1Arrow[B,C](f: B => C): InfixFn1Arrow[B,C] =
new InfixFn1Arrow(f)
implicit def function0Arrow[C](f: => C): InfixFn1Arrow[Unit,C] =
new InfixFn1Arrow(Unit => f)
.--------------------. .------------------------.
| .---------. | | .----------. |
| | get num |---. | | .-| add real |-. |
| '---------' \ | | / '----------' \ | .-----------. .-------.
| >--|--->|--< >--|--->| to string |--->| print |
| .---------. / | | \ .----------. / | '-----------' '-------'
| | get num |---' | | '-| add imag |-' |
| '---------' | | '----------' |
'--------------------' '------------------------'
type Complex =
(Float, Float)
def show[A](a: A): String =
.toString
a
val add: Float => Float => Float =
=> y => x + y
x
val addC: ((Complex, Complex)) => Complex =
=> (add(xy._1._1) *** add(xy._1._2))(xy._2._1, xy._2._2)
xy
def getC(): Complex = {
print("real: ")
val r: Float =
. toFloat
readLine
print("imaginary: ")
val i: Float =
. toFloat
readLine
(r, i)
}
val infixFn1ArrowDemo: Unit => Unit =
(getC(), getC()) >>> addC >>> show >>> println
infixFn1ArrowDemo()
This file is literate Scala, and can be run using Codedown:
$ curl \
https://earldouglas.com/posts/type-classes/arrow.md \
https://earldouglas.com/posts/type-classes/fn1arrow.md |
codedown scala > script.scala
$ scala -nc script.scala
real: 1
imaginary: 2
real: 3
imaginary: 4
(4.0,6.0)