2016-07-13 2 views
1

Я получаю ошибку несоответствия типа, и я не могу понять, почему.Для понимания и фьючерсов есть несоответствие типа

found:  scala.concurrent.Future[UserSales] 
required:  Option[UserSales] 

     userSalesOpt <- getOrSetUserSales(userSalesCacheKey) 

I have tried creating another for {} clause but that didn't solve the issue. What should I be doing as I am stuck?? 

Вот методы, которые я использую:

UserDAO 
    def getByUsername(name: String): Future[Option[User]] 

UserController: 
    def getOrSetUserSales(key: String): Future[Option[UserSales]] 

class UserController ... { 

    def index = Action.asyc { 
    val maybeUserSalesOpt: Future[Option[UserSales]] = for { 
     userOpt <- userDao.getByUsername(name) 
    } yield { 
     for { 
      user <- userOpt 
      userSalesCacheKey = name + "whatever" 
      userSalesOpt <- getOrSetUserSales(userSalesCacheKey) 
     } yield { 
     for { 
      userSales <- userSalesOpt 
     } yield userSales 
     } 
    } 

    for { 
     maybeUserSales <- maybeUserSalesOpt 
    } yield { 
     if(maybeUserSales.isDefined) { 
     Ok("found") 
     } else { 
     Ok("error") 
     } 

    } 

    } 

} 

ответ

1

тип рассогласование происходит из определения для-понимания. Получаемый тип должен быть таким же, как тип записи.

Итак, если у вас есть понимание в списке, вы знаете, что результирующий тип также является списком.

for(i <- List(Some(1), None, Some(2)); j <- i) yield j 
res: List[Int] = List(1, 2) 

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

import scala.concurrent.Future 
import scala.concurrent.ExecutionContext.Implicits.global 

for(i <- Future.apply(Option(2)); j <- i) yield j 
<console>:**: error: type mismatch; 
found : Option[Int] 
required: scala.concurrent.Future[?] 
       for(i <- Future.apply(Option(2)); j <- i) yield j 
               ^

Вы пытаетесь вернуть один вариант, тогда как тип возвращаемого значения должен быть будущее.


Вот как решить такого рода проблемы в Scala (я отвлекаюсь все, так что он компилирует):

// Dummy types 
type UserSales = String 
type User = String 

// Types of the main functions we have 
type GetByUsername = String => Future[Option[User]] 
type GetOrSetUserSales = String => Future[Option[UserSales]] 

// Type of the function I want 
type UserSaleGetter = (String, String) => Future[Option[UserSales]] 

// A function that solves our problem (function combinator) 
def makeConditionalUserSalesGetter(userGetter: GetByUsername, 
            salesGetter: GetOrSetUserSales): UserSaleGetter = { 
    (userName: String, prodName: String) => 
     for(optUser <- userGetter(userName); p <- salesGetter(userName+prodName)) 
      yield p 
} 

Теперь мы можем использовать комбинированную функцию (с типом UserSaleGetter), чтобы дать пользователю и продукт и вернуться Future[Option[UserSales]].

+0

Но мой тип возврата - будущее [Option [UserSales]]? – Blankman

+0

В цикле 'user <- userOpt ...' вы начинаете с Option (userOpt), и вы возвращаете Future (это происходит из' getOrSetUserSales() '). Это то, что компилятор жалуется. – marios