2016-07-26 13 views
0

In Idris, Typen sind erstklassige Werte:Verwenden von Typen als erstklassige Werte in Scala?

FooType : (Type, Type) 
FooType = (Int, Int) 
fst FooType -- Int : Type 

Ich mag würde irgendwie diese Funktion in Scala verwenden, so dass ich Typ-Mitglieder über verschiedene Methoden wiederverwenden können:

class Foo { 
    type FooType = (Int, Int) 

    def foo : FooType = { ... } 
    def bar : Int = { ... } // Here I would like to reuse the first type of FooType (Int) 
} 

Was das ist Empfohlene Methode, dies in Scala zu erreichen?

+0

'FooType' ist für den Bereich verfügbar, auf dem es definiert wurde. Was meinst du mit * Wiederverwendung von Typmitgliedern über verschiedene Methoden *? Was hindert Sie daran, 'FooType' überall zu verwenden? –

+0

@YuvalItzchakov 'FooType' hat den Typ' Tuple2 [T1, T2] ', ich möchte in der Lage sein, Methoden zu definieren, die auf Typmembern von' FooType' basieren, z. "' FooType._1' "(T1) statt einfach' Int', damit meine definierten Typen wiederverwendet werden. Ich bin mir nicht sicher, ob das möglich ist. – jarandaf

+0

Oh, ich verstehe. Sie möchten, dass 'FooType' basierend auf Mitgliedern einer Klasse abgeleitet wird? –

Antwort

0

Ich denke, die nächst Sie erhalten können, ist eine Art Element verwendet:

trait TupleType[T] { type Member = T } 

implicit def toTuple[T](a: (T, T)) = new TupleType[T] {} 

type FooType = TupleType[Int] 

def foo: FooType = (1, 2) 
def bar: FooType#Member = 1 

Sonst könnte man nur eine Art Alias ​​für Ihren Tupel Elementtyp verwenden:

type A = Int 
type FooType = (A, A) 

def foo: FooType = (1, 2) 
def bar: A = 1 
0

Es ist mehr oder weniger möglich, wenn Sie die notwendige Infrastruktur selbst erstellen. In scala-Typ sind die Level-Funktionen nicht wirklich erstklassig. Sie werden auf Bibliotheksebene mit Implicits implementiert.

scala> :paste 
// Entering paste mode (ctrl-D to finish) 

sealed trait Deconstruct[T <: (_,_)] { 
    type fst 
    type snd 

    def fst(t: T): fst 
    def snd(t: T): snd 
} 

object Deconstruct { 
    implicit def mkDeconstruct[A,B] = new Deconstruct[(A,B)] { 
    type fst = A 
    type snd = B 

    def fst(t: (A,B)): A = t._1 
    def snd(t: (A,B)): B = t._2 
    } 
} 

// Exiting paste mode, now interpreting. 

defined trait Deconstruct 
defined module Deconstruct 

scala> type FooType = (Int,Int) 
defined type alias FooType 

scala> def foo: FooType = (1,2) 
foo: (Int, Int) 

scala> def bar(implicit d: Deconstruct[FooType]) = d.fst(foo) 
bar: (implicit d: Deconstruct[(Int, Int)])d.fst 

scala> bar 
res0: Int = 1