2012-12-23 2 views
10

Capisco che un metodo può avere codice come questo:Cosa significano in Scala le frecce di grasso multiple e consecutive nei parametri del metodo?

def m(p1:Int => Int) ... 

Il che significa che questo metodo richiede una funzione che restituisce un p1 Int

Ma durante la navigazione in Play! codice del framework ho trovato un tratto con i metodi indecifrabili:

trait Secured { 

    def username(request: RequestHeader) = request.session.get(Security.username) 

    def onUnauthorized(request: RequestHeader) = Results.Redirect(routes.Auth.login) 

    def withAuth(f: => String => Request[AnyContent] => Result) = { 
    Security.Authenticated(username, onUnauthorized) { user => 
     Action(request => f(user)(request)) 
    } 
    } 

    /** 
    * This method shows how you could wrap the withAuth method to also fetch your user 
    * You will need to implement UserDAO.findOneByUsername 
    */ 
    def withUser(f: User => Request[AnyContent] => Result) = withAuth { username => implicit request => 
    UserDAO.findOneByUsername(username).map { user => 
     f(user)(request) 
    }.getOrElse(onUnauthorized(request)) 
    } 
} 

Play! Scala Security

Cosa significa il f: User => Request[AnyContent] => Result significa? A prima vista sembra un metodo che restituisce una funzione r di tipo Request; r restituisce quindi un Result.

È questa la giusta ipotesi?

risposta

16

Cosa significa f: Utente => Richiesta [AnyContent] => Risultato? A prima vista sembra un metodo che restituisce una funzione r di tipo Request; r quindi restituisce un risultato.

f restituisce una funzione di tipo Request[AnyContent] => Result, cioè una funzione che prende un Request[AnyContent] e restituisce una Result.

In altre parole f è una funzione al curry. Potresti chiamarlo come f(user)(request) per ottenere un Result.

+0

Ok, freddo. Ma perché è necessario specificarlo? Perché il compilatore non può inferire il tipo restituito da 'Request'? Modifica: non importa, suppongo che i sottotipi di richiesta possano restituire diversi tipi di risultati, quindi questo è utile. –

+2

@ CameronA.Ellis Non sono sicuro di aver capito il tuo commento. L'oggetto 'Request' non restituisce nulla. La funzione restituita da 'f', che ha tipo' Request [AnyContent] => Result' restituisce un 'Result'. Il tipo di ritorno non può essere escluso dal tipo di una funzione perché in questo caso sembrerebbe che 'f' abbia restituito un oggetto' Request' - non una funzione che accetta un oggetto 'Request', che è piuttosto diverso. – sepp2k

+0

grazie per aver chiarito questo. Ha perfettamente senso ora. –

1

def withAuth(f: => String => Request[AnyContent] => Result) mezzi, che f è un parametro per nome, e si può scrivere qualcosa del genere:

withAuth { 
    logger.info("Here we go") 
    ... 
    chooseTheAction("list") 
} 

dove chooseTheAction prende un String e restituisce una funzione di eseguire una richiesta, Request[AnyContent] => Result