How to create a partial function that takes the whole domain, but depends on some state?

A question related to functional programming.

"One line of code is worth a thousand words," therefore:

class Entry {
  var entryOrderId: Option[Int]
  def closeEntry(closeOrder: Order) = {
    require(entryOrderId.isDefined)
    ...
  }
}

Question: to close a record, it is necessary to define entryOrderId. I do not want to throw an exception (using the "require" function), and I prefer not to return a Try (Success / Failure) object, because the caller does not expect any return value. How would you create this feature?

(Nb: I'm tagged with Scala, but the language is wrong here ...)

+4
source share
2 answers

, , foreach entryOrderId. , entryOrderId .

class Entry {
  var entryOrderId: Option[Int]
  def closeEntry(closeOrder: Order) = entryOrderId foreach { id =>
    // do something with the `id` ...
  }
}
+3

closeEntry , entryOrderId, , . , Entry. , , closeEntry.

class Order
case class Entry[T <: Option[Int]](entryOrderId: T) {
  def closeEntry(closeOrder: Order)(implicit ev: T =:= Some[Int]): Unit = {
    entryOrderId.get + 42
  }
}

, closeEntry Entry[Option[Int]] Entry[None.type]:

scala> Entry(Some(42)).closeEntry(new Order)

scala> Entry(None).closeEntry(new Order)
<console>:11: error: Cannot prove that None.type =:= Some[Int].
              Entry(None).closeEntry(new Order)
                                    ^

:

  • (Int )
  • , Entry[Some[Int]] Entry[Option[Int]] , , Entry[Some[Int]]
  • , : p

, , , :

import scala.language.higherKinds

class Order
case class Entry[T[_]](entryOrderId: T[Int]) {
  def closeEntry(order: Order)(implicit withId: WithId[T]): Unit = {
    withId.getId(this) + 42
  }
}
implicit object Entry extends HasId[Some] {
  def getId(entry: Entry[Some]): Int = entry.entryOrderId.get
}

trait WithId[T[_]] {
  def getId(entry: Entry[T]): Int
}

(, - Entry[Some] Entry[Some[Int]])


, :

sealed trait Entry
case class EntryWithId(val entryOrderId: Int) extends Entry {
  def closeEntry(closeOrder: Order): Unit = {
    ...
  }
}
class NewEntry() extends Entry

, - .

+2

Source: https://habr.com/ru/post/1568355/


All Articles