2015-05-17 8 views
8

In Scala, le classi generiche come Future, Option e List hanno tutti i metodi map e flatMap. Come ho capito, tutti loro sono come Functors in Haskell.Perché non c'è un tratto "Functor" in Scala?

Mi stavo chiedendo perché non v'è un tratto (interfaccia) chiamato Functor in Scala ..

Qualcuno ha idee su questo?

+2

Perché Scala non è un linguaggio di ricerca? Haskell è un linguaggio meno generale/pratico di Scala, si potrebbe dire. – AJFarmar

+10

@ AJFarmar, dal momento che 'Functor' ha un immenso valore pratico, non sono sicuro di come questo lo risponda. Sarebbe meglio esprimere il motivo per cui non ha, ad esempio, un tratto di categoria. – dfeuer

+1

@dfeuer Ma la parola stessa deriva dalla teoria delle categorie, che non mi aspetto di apparire in Scala o in qualsiasi altro linguaggio tradizionale. Forse è sotto un nome diverso? – AJFarmar

risposta

11

Come sarebbe un tratto del genere? Ricorda, il functor è determinato da una funzione fmap che solleva una funzione regolare a una funzione che agisce su valori "functorial" (o, in alternativa, applica una funzione regolare ai contenuti del functor). Il più vicino a cui riesco a pensare è

trait Functor[T] { 
    type Self[U] <: Functor[U] 
    def fmap[U](f: T => U): Self[U] 
} 

Tale definizione non è veramente utile e relativamente complessa. I tratti non hanno la necessaria flessibilità per l'astrazione di concetti di alto livello come i funtori.

Tuttavia, Scala ha classi tipo, vale a dire, è possibile utilizzare i tratti ei parametri impliciti in un modo intelligente per implementare il modello di tipo di classe:

trait Functor[F[_]] { 
    def fmap[T, U](f: T => U)(v: F[T]): F[U] 
} 

implicit object OptionFunctor extends Functor[Option] { 
    def fmap[T, U](f: T => U)(v: Option[T]): Option[U] = v match { 
    case Some(r) => Some(f(r)) 
    case None => None 
    } 
} 

def doSomething[F[_]: Functor](f1: F[Int], f2: F[String]): F[Long] = ??? // whatever 
// equivalent to: 
// doSomething :: Functor f => f Int -> f String -> f Long 
// in Haskell 

E questo è esattamente ciò che scalaz fornisce.

Per quanto riguarda il motivo per cui questo non è presente nella libreria standard, non lo so. Forse il modello di classe del tipo non è stato scoperto immediatamente, e la biblioteca era già stata formata in quel momento. Forse è solo perché questi sono concetti un po 'avanzati che non appartengono veramente alla libreria standard. Forse qualcos'altro.

+1

"Non so" - buona risposta! – ZhekaKozlov

+1

@ZhekaKozlov, credo di aver risposto alla domanda originale (perché non c'è alcun functor * trait * in stdlib) - non è proprio così utile e conveniente. Il "non so" riguardava le lezioni di tipo. –

+1

Questo è effettivamente errato. La std lib di Scala ha alcune typeclass: Numeric (== Haskell's Num), Integral (== integrale), Fractional (== Fractional), Ordering (== Ord), Equiv (== Eq). – ZhekaKozlov

Problemi correlati