我想定义一个元组(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")
}
}
答案 0 :(得分:0)
您可以通过利用以下内容在Scala中完成此操作 -
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)
^