函数域与Haskell / Scala中另一个集合的元素的相关性

时间:2015-06-16 16:42:02

标签: scala haskell

我想定义一个元组(A, f),这样A是一组整数,f是从这个集合到整数的函数。我想强调f的域依赖于A元素。例如,如果A被定义为A={1,2},则f={1->10,2->15}是f的有效实例,但f={1->10,2->15,3->20}不是有效的f;因为在第二种情况下,f的域不限于A.

我的问题:

有没有办法在Haskell / Scala中定义(A, f),以便Haskell / Scala类型系统强制执行f到A内容的可靠性。 (我怀疑这种情况是dependent types的一个例子。我是对的吗?)

更新

我正在为上述问题添加一段Scala代码,以增加更多清晰度。拥有以下代码,非常具体的问题是:是否有任何方法(使用该语言的输入系统)使我们无需在下面的代码中编写throw语句?也就是说,使用语言输入系统,我们说f的域只限于A元素?

class ClassA (val A:Set[Int], val f:Map[Int,Int] ){
    if (!A.equals(f.keySet)){
          throw new IllegalArgumentException("f domain and set A do not match")
     }
  }

1 个答案:

答案 0 :(得分:0)

您可以通过利用以下内容在Scala中完成此操作 -

  • shapeless库将整数编码为Nat值(自然数)
  • 使用f方法模拟函数调用的对象apply()
  • 在该对象中定义的类型类F[N],它强制执行可接受的输入类型
scala> :paste
// Entering paste mode (ctrl-D to finish)

import shapeless._

object f {
  def apply(n: Nat)(implicit ev: F[n.N]) = ev()
  sealed trait F[N] { def apply(): Int }
  private def inst[N](r: Int): F[N] = new F[N] { def apply(): Int = r }
  implicit val one = inst[Nat._1](10)
  implicit val two = inst[Nat._2](15)
}

// Exiting paste mode, now interpreting.

import shapeless._
defined object f

scala> f(1)
res0: Int = 10

scala> f(2)
res1: Int = 15

scala> f(3)
<console>:16: error: could not find implicit value for parameter ev: f.F[shapeless.Succ[shapeless.Succ[shapeless.Succ[shapeless._0]]]]
       f(3)
        ^