gpt4 book ai didi

scala - 对连续元素具有类型约束的列表

转载 作者:行者123 更新时间:2023-12-04 15:10:28 26 4
gpt4 key购买 nike

是否可以定义一个列表类型,其中每对连续元素都满足某种关系(约束)。例如,可以组合函数的函数列表:

val f1: A => B = ???
val f2: B => C = ???
val f3: C => D = ???

type SafeList = ??? // how to define this?

val fs: SafeList = f1 :: f2 :: f3 :: HNil // OK

val fs: SafeList = f1 :: f3 :: HNil // ERROR

最佳答案

通常不可能使用类型别名来描述这样有趣的约束——相反,您需要一个类型类来作为类型具有某些属性的证据。

对于 Shapeless,通常可以使用库提供的类型类来实现这一点,但我认为这里不是这种情况。幸运的是,编写自己的代码并不太难:

import shapeless._

// Evidence that an hlist is made up of functions that can be composed.
trait Composable[L <: HList] {
type In
}

object Composable {
type Aux[L <: HList, In0] = Composable[L] { type In = In0 }

implicit def composable0[A, B]: Aux[(A => B) :: HNil, A] =
new Composable[(A => B) :: HNil] {
type In = A
}

implicit def composable1[A, B, T <: HList]
(implicit tc: Aux[T, B]): Aux[(A => B) :: T, A] =
new Composable[(A => B) :: T] {
type In = A
}
}

def composable[L <: HList: Composable] {}

我们在这里所做的是描述如何使用单例归纳建立证据 HList作为基本情况。在每一步我们都使用 In type 成员来跟踪下一个(即列表中较早的)函数的输出类型必须是什么。

并确认它符合我们的预期:
scala> composable[(Int => String) :: (String => Char) :: HNil]

scala> composable[(Int => Long) :: (Long => Char) :: (Char => String) :: HNil]

scala> composable[(Int => String) :: (Symbol => Char) :: HNil]
<console>:23: error: could not find implicit value for evidence parameter...

前两个工作得很好,而第三个不能编译。

关于scala - 对连续元素具有类型约束的列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28840812/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com