加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

StringOrInt从Idris – > Scala?

发布时间:2020-12-16 09:17:41 所属栏目:安全 来源:网络整理
导读:Type Driven Development with Idris介绍这个程序: StringOrInt : Bool - TypeStringOrInt x = case x of True = Int False = String 在Scala中怎么写这样的方法? 解决方法 Alexey的答案是好的,但是如果我们将其嵌入到更大的上下文中,我们可以得到一个更广
Type Driven Development with Idris介绍这个程序:

StringOrInt : Bool -> Type
StringOrInt x = case x of
                  True => Int
                  False => String

在Scala中怎么写这样的方法?

解决方法

Alexey的答案是好的,但是如果我们将其嵌入到更大的上下文中,我们可以得到一个更广泛的Scala渲染这个函数.

Edwin在函数valToString中显示了使用StringOrInt,

valToString : (x : Bool) -> StringOrInt x -> String
valToString x val = case x of
                         True => cast val
                         False => val

换句话说,valToString采用一个Bool第一个参数,它将其第二个参数的类型固定为Int或String,并将后者作为其类型的适当字符串呈现.

我们可以将其转换为Scala,如下所示

sealed trait Bool
case object True extends Bool
case object False extends Bool

sealed trait StringOrInt[B,T] {
  def apply(t: T): StringOrIntValue[T]
}
object StringOrInt {
  implicit val trueInt: StringOrInt[True.type,Int] =
    new StringOrInt[True.type,Int] {
      def apply(t: Int) = I(t)
    }

  implicit val falseString: StringOrInt[False.type,String] =
    new StringOrInt[False.type,String] {
      def apply(t: String) = S(t)
    }
}

sealed trait StringOrIntValue[T]
case class S(s: String) extends StringOrIntValue[String]
case class I(i: Int) extends StringOrIntValue[Int]

def valToString[T](x: Bool)(v: T)(implicit si: StringOrInt[x.type,T]): String =
  si(v) match {
    case S(s) => s
    case I(i) => i.toString
  }

在这里,我们使用各种Scala有限的依赖类型的功能来编码Idris的全频谱依赖类型.

>我们使用单例类型True.type和False.type从值级别到类型级别.
>我们将函数StringOrInt编码为由单例Bool类型索引的类型类,每种情况下的Idris函数由不同的隐式实例表示.
>我们将valToString写为Scala依赖方法,允许我们使用Bool参数x的单例类型来选择隐式StringOrInt实例si,后者又决定了固定第二个参数类型v的类型参数T.
>我们通过使用所选的StringOrInt实例将v参数解压缩到Scala GADT中,使得Scala模式匹配可以改善案例RHS上的v类型,从而对Idris valToString中的依赖模式进行编码.

在Scala REPL上执行此操作,

scala> valToString(True)(23)
res0: String = 23

scala> valToString(False)("foo")
res1: String = foo

许多篮球跳过,很多偶然的复杂性,但是,可以做到这一点.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读