Создание объектов скалярного эффекта - PullRequest
0 голосов
/ 04 декабря 2018

Я пытаюсь использовать монад IO [E, A] в скаласе для очень эффективного кода.

Код, который я пытаюсь переписать с помощью IO [E, A] ввысокий уровень требует метаданных о файле, который хранится в облаке.Код пытается:

  1. загрузить файл
  2. извлечь строки из файла
  3. построить файл, содержащий текстовое содержимое файла
  4. pojo к какой-то очереди / отдыху

Детали шагов не так важны, но я думал о том, чтобы сделать что-то вроде:

def processShareActivity(fileObject: FileObject): IO[ProcessFileFailure, IndexResponse] = {
    for {
        file <- downloadFile (fileObject)
        text <- extractText (file)
        searchFileObject <- IO.point(buildSearchFileObject (fileObject, file, text))
        indexedResponse <- indexSearchFileObject (searchFileObject)
    } yield indexedResponse
}

def indexSearchFileObject(fileObject: SearchFileObject): IO[IndexFailure, IndexResponse] = ???

def buildSearchFileObject(fileObject: FileObject, file: File, str: String): SearchFileObject = ???

def extractText(file: File): IO[ExtractionFailure, String] = ???

def downloadFile(fileObject: FileObject): IO[DownloadFileFailure, File] = ???

Проблема в том, что экземпляры IO[E,A] и IO[F,B], похоже, не скомпонованы.То есть, например, поскольку сигнатура ввода-вывода downloadFile возвращает DownloadFileFailure для сценария ошибки, а extractText возвращает ExtractionFailure, эти монады не могут составлять в понимании for.

Есть ли простой способ для моего понимания верхнего уровня for составить так, чтобы это привело к IO[ProcessFileFailure, IndexResponse], где ProcessFileFailure - это какой-то объект оберточного сбоя вокруг разного рода отказов, которые могутслучится в подметодах?

1 Ответ

0 голосов
/ 04 декабря 2018

К сожалению, вам нужен способ объединить эти ошибки в общую:

, например:

sealed trait ProcessFileFailure
object ProcessFileFailure {
   case class Index(e: IndexFailure) extends ProcessFileFailure
   case class Extraction(e: ExtractionFailure) extends ProcessFileFailure
   case class Download(e: DownloadFileFailure) extends ProcessFileFailure
}

И ваше понимание станет:

for {
        file <- downloadFile (fileObject).leftMap(ProcessFileFailure.Download)
        text <- extractText (file).leftMap(ProcessFileFailure.Extraction)
        searchFileObject <- IO.point(buildSearchFileObject (fileObject, file, text))
        indexedResponse <- indexSearchFileObject (searchFileObject).leftMap(ProcessFileFailure.Index)
    } yield indexedResponse

Это неловко, но у него есть то преимущество, что он способен хранить все, что пошло не так, и точно контекст, в котором это произошло.

...