在Scala中使用类型作为第一类值?

时间:2016-07-26 08:44:05

标签: scala idris

在Idris中,类型是一流的值:

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

我想在Scala中以某种方式使用此功能,以便我可以在不同方法上重用类型成员:

class Foo {
  type FooType = (Int, Int)

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

在Scala中实现此目的的推荐方法是什么?

2 个答案:

答案 0 :(得分:0)

我认为最接近的是使用类型成员:

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

否则,您可以为元组成员类型使用类型别名:

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

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

答案 1 :(得分:0)

如果您自己创建必要的基础架构,这或多或少是可能的。在scala类型中,级别函数并不是真正的第一类。它们是在图书馆一级实施的。

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