Tipo di mappa per Try [T]

1

Stavo guardando il tipo di map per Try[T] in Scala, che è:

def map[S](f: T=>S): Try[S]

Da Haskell, sono abituato al tipo di mappa che è:

map :: (a->b)->[a]->[b]

Questo sembra molto logico. Mappa prende una funzione e un gruppo di elementi e applica quella funzione su tutti gli elementi dell'insieme.

Tuttavia, non capisco cosa voglia dire il tipo Scala. Se map trasforma Try[S] in Try[T] , perché il tipo non è:

def map[Try[T]](f:T=>S): Try[S]
    
posta octavian 04.06.2016 - 17:19
fonte

2 risposte

7

Scala è un linguaggio orientato agli oggetti. Nei linguaggi orientati agli oggetti, i metodi hanno accesso speciale a un argomento "destinatario" designato (in genere chiamato this o self ). Questo parametro di solito non è esplicitato nella firma del metodo (Python è un'eccezione).

Quindi, devi ricordare che il metodo map è in realtà definito come un membro di un tratto o classe e che esiste un ulteriore parametro invisibile di zeroth il cui tipo è il tipo della classe o tratto il metodo è membro di.

In questo caso particolare, il tipo è Try[T] .

Quindi, se map fosse una funzione indipendente, il suo tipo sarebbe:

def map[S, T](this: Try[T], f: T ⇒ S): Try[S]

che è equivalente al tipo Haskell

map :: Try t → (t → s) → Try s
    
risposta data 04.06.2016 - 18:59
fonte
2

Ci sono tre parti in questo tipo di firma:

  • Corrente, tipo originale, T
  • Tipo di ritorno, U
  • Trasformazione, f: (T) => U

Poiché stai guardando una classe generica con un metodo map (anziché una funzione autonoma), la variabile di tipo T è definita sopra, in una classe type signature: Try[T] . Questo spiega perché non c'è T nella parentesi di map[...] . È già lì, non devi specificarlo di nuovo (e non puoi).

Quindi, semplicemente, la firma della classe Try[T] fornisce un contesto sufficiente per consentire al compilatore di conoscere il tipo di sorgente.

In Haskell, hai a che fare con le funzioni, non con i metodi delle classi, quindi devi dichiarare gli input in modo esplicito. Non c'è this o self in Haskell.

In Scala, le lettere tra parentesi [T] sono variabili di tipo dichiarazioni , mentre in (T) => U diventano firme di tipi effettive. Onestamente, in casi come questo, penso che sarebbe sufficiente scrivere solo def map(f: (T) => U): Try[U] (non notare parentesi dopo map ), ma non posso discutere con il compilatore. Devi solo dire al compilatore che userai U nella seguente segnatura tipo.

    
risposta data 04.06.2016 - 19:19
fonte

Leggi altre domande sui tag