3
\$\begingroup\$

I thought up a function that provides types with InputStream and OutputStream:

trait Format[A] {
  def read(i: TypedInput): A
  def write(o: TypedOutput, a: A)
}
trait TypedInput {
  def i: InputStream
  def reads[A](implicit f: Format[A]) = f.read(this)
}
trait TypedOutput {
  def o: OutputStream
  def writes[A](a: A)(implicit f: Format[A]) = f.write(this, a)
}
// and implicit conversions from InputStream to TypdeInput, etc

For example, given a type class of Format[A], now an InputStream can read an instance of A by i.reads[A] and i.reads(FormatOfA):

implicit object IntFormat extends Format[Int] {
  def read(i: TypedInput) = new DataInputStream(i.i).readInt
  def write(o: TypedOutput, a: Int) = new DataOutputStream(o.o).writeInt(a)
}
val i: InputStream = ???
val o: OutputStream = ???
i.reads[Int]
o.writes(3)

When I first thought up this, it looked very Scala with type classes, but now I think it's still very Java, because it just extends java.io so it looks fancy, only with type classes. Please give me some advice to implement this function's concept in more Scala way!

\$\endgroup\$
  • \$\begingroup\$ Creating a new object (resp DataInputStream(i.i) and DataOutputStream(o.o)) does not seem really efficient. \$\endgroup\$ – skiwi Jul 28 '14 at 6:44
  • \$\begingroup\$ @skiwi Yes, they have some array buffers inside, so it's not efficient to instantiate them often, but I'm doing it here just to make it simple and clear. If I really use this function, then I will make TypeInputStream#i be DataInputStream and make two implementing classes: class ImplD(val i: DataInputStream) extends AnyVal with TypeInputStream and class Impl(n: InputStream) extends TypeInputStream { val i = new DataInputStream(n) }, then make an implicit conversion function: implicit def tpe(i: InputStream) = i match { case i: DataInputStream => new ImplD(i); case i => new Impl(i) }. \$\endgroup\$ – Ryoichiro Oka Jul 28 '14 at 16:44
  • \$\begingroup\$ Well.. my question's main point is still how to implement this function's concept more like Scala. The reason why I wrote the code above is, just to let you (and others) know that I'm sure that the example code in the question is not efficient if used for real, and that I know how to make it efficient when I give up to make it more Scala. \$\endgroup\$ – Ryoichiro Oka Jul 28 '14 at 17:55
  • 2
    \$\begingroup\$ The question includes a complete working example that accomplishes a specific task (except for the instantiation of the underlying InputStream and OutputStream). I think that that is sufficient to make this an on-topic question. \$\endgroup\$ – 200_success Jul 28 '14 at 18:16
  • \$\begingroup\$ @200_success Thank you, how should I question this sorts next time? \$\endgroup\$ – Ryoichiro Oka Jul 28 '14 at 18:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.