gpt4 book ai didi

scala - 无形:IsHCons,未找到隐式

转载 作者:行者123 更新时间:2023-12-04 17:08:52 25 4
gpt4 key购买 nike

我试图让这个相当愚蠢的例子工作,然后计划将它扩展到更有意义的东西。

但到目前为止没有运气:我得到 could not find implicit value for parameter ihc
我错过了什么?

sealed trait Field[T] { def name: String }
case class IntegerField(name: String) extends Field[Int]
val year = IntegerField("year")

val test = (year :: 23 :: HNil) :: (year :: 2 :: HNil) :: HNil

type TypedMap = IntegerField :: Int :: HNil

def get[L <: HList : <<:[TypedMap]#λ]
(key: IntegerField, list: L)
(implicit ihc: IsHCons.Aux[L, TypedMap, L]
): Option[Int] = {

if( list == HNil ) return None
val elem: TypedMap = list.head
if( elem.head == key ) Some(elem.tail.head)
else get(key, list.tail)

}

get(year, test)

最佳答案

当你写 IsHCons.Aux[L, TypedMap, L]你要的是 hlist L 的证据有头TypedMap和尾部L ,这意味着它是一个无限的 hlist,这是不可能的,因为 Scala 不允许这种任意递归类型(例如,尝试编写类似 type Foo = Int :: Foo 的东西——你会得到一个“非法循环引用”错误)。这也可能不是您想要的。

一般来说,您不太可能使用 IsHCons在 Shapeless 中很多,因为在类型中指示您想要的结构几乎总是更好。例如,以下两个定义做同样的事情:

import shapeless._, ops.hlist.IsHCons

def foo[L <: HList](l: L)(implicit ev: IsHCons[L]) = ev.head(l)

和:
def foo[H, T <: HList](l: H :: T) = l.head

但是第二个显然更可取(它更清楚,它不需要在编译时找到额外的类型类实例等),并且几乎总是可以编写任何您想要这样做的内容。

另请注意,需要 IsHCons实例意味着这里的递归不会按规定工作——你不能调用 getHNil 上,因为编译器无法证明它是 HCons (因为它不是)。

你确定你需要一个 hlist 吗?如果您要求 hlist 的所有成员都属于 TypedMap 类型,你还不如用Shapeless的 Sized (如果你想要类型来捕捉长度)或者甚至只是一个普通的旧 List .

如果您真的,真的想使用 HList在这里,我建议编写一个新的类型类:
trait FindField[L <: HList] {
def find(key: IntegerField, l: L): Option[Int]
}

object FindField {
implicit val findFieldHNil: FindField[HNil] = new FindField[HNil] {
def find(key: IntegerField, l: HNil) = None
}

implicit def findFieldHCons[H <: TypedMap, T <: HList](implicit
fft: FindField[T]
): FindField[H :: T] = new FindField[H :: T] {
def find(key: IntegerField, l: H :: T) = if (l.head.head == key)
Some(l.head.tail.head)
else fft.find(key, l.tail)
}
}

def get[L <: HList](key: IntegerField, l: L)(implicit
ffl: FindField[L]
): Option[Int] = ffl.find(key, l)

进而:
scala> get(IntegerField("year"), test)
res3: Option[Int] = Some(23)

scala> get(IntegerField("foo"), test)
res4: Option[Int] = None

这是 Shapeless 中非常常见的模式——您归纳性地描述如何对空的 hlist 执行操作,然后对头部加在尾部的 hlist 执行操作,您知道如何对其执行操作,等等。

关于scala - 无形:IsHCons,未找到隐式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29331173/

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