List 过滤器在shapeless、Scala中的使用
可以很容易地按类型在shapeless中过滤List 过滤器在shapeless、Scala中的使用,list,scala,filter,shapeless,heterogeneous,List,Scala,Filter,Shapeless,Heterogeneous,可以很容易地按类型在shapeless中过滤HList: val hlist = 1 :: 2 :: "3" :: true :: false :: HNil hlist.filter[Int] 但是如何制作自定义类型过滤器?我想要这样的smth:例如,我得到了一些函数的列表: def function1(s: String) = s.toInt def function2(s: String) = s.toDouble def function3(i: Int) = i.toDouble
HList
:
val hlist = 1 :: 2 :: "3" :: true :: false :: HNil
hlist.filter[Int]
但是如何制作自定义类型过滤器?我想要这样的smth:例如,我得到了一些函数的列表:
def function1(s: String) = s.toInt
def function2(s: String) = s.toDouble
def function3(i: Int) = i.toDouble
val hflist = function1 _ :: function3 _ :: function2 _ :: HNil
hflist customFilter[String] //> function1 _ :: function2 _ :: HNil
因此,使用此过滤器后,将构造从类型String
到其他类型的函数列表
我本来想用map来做这个,但没有成功
版本
有关我的评论的更多信息:
我试着在地图上测试这个想法:
因此,如果我得到一些列表(让我们使用hlist
&hflist
):
非常有趣,为什么它编译和工作不正确?因为我认为它不起作用,所以对象不能以这种方式使用类型参数…最简单的方法是使用折叠。首先,我们需要一个多态函数,如果每个项都具有所需的类型(
String=>a
,对于某些a
),则将其添加到累加器中,否则忽略它:
trait ignore extends Poly2 {
implicit def default[A, L <: HList] = at[A, L]((_, l) => l)
}
object keepStringFunc extends ignore {
implicit def stringFunc[A, L <: HList] = at[String => A, L](_ :: _)
}
您还可以在Filter
、FilterAux
(或Filter.Aux
)等模型上编写您自己的类型类,如果您试图掌握无形状的诀窍,那么这样做将是一个很好的练习,但是foldRight
要简单得多
更新:实际上,值得一提的是,有一种更简洁的方法可以使用
flatMap
:
trait skip extends Poly1 {
implicit def default[A] = at[A](_ => HNil)
}
object grabStringFunc extends skip {
implicit def stringFunc[A] = at[String => A](_ :: HNil)
}
val filtered = hflist flatMap grabStringFunc
我个人觉得foldRight的版本更为明显,但这个版本也相当优雅
回应您的评论:您可以让解决方案更通用一些,如下所示:
trait skip extends Poly1 {
implicit def default[A] = at[A](_ => HNil)
}
trait grabFuncFrom[T] extends skip {
implicit def stringFunc[A] = at[T => A](_ :: HNil)
}
object grabStringFunc extends grabFuncFrom[String]
val filtered = hflist flatMap grabStringFunc
但您仍然需要最后一步,即创建更高秩函数作为对象(有关此问题的一些讨论,请参见此处的和Miles的评论)。omg,这是一个非常好的决定;太多了!我还将尝试编写自己的
过滤器。谢谢!嗯,对于我的问题,我们可以在函数中传递prameter吗,我的意思是smth,比如def stringFunc[a]=at[T=>a](u216;:HNil)
?为什么它在编译,事实上为什么它不起作用?我在路上写自己的代码>过滤器< /代码>:谢谢!y、 为了理解无形。我希望我能多次投票支持你的答案。我添加了一些关于我的评论的信息,我尝试了什么。谢谢你的时间!:)
trait skip extends Poly1 {
implicit def default[A] = at[A](_ => HNil)
}
object grabStringFunc extends skip {
implicit def stringFunc[A] = at[String => A](_ :: HNil)
}
val filtered = hflist flatMap grabStringFunc
trait skip extends Poly1 {
implicit def default[A] = at[A](_ => HNil)
}
trait grabFuncFrom[T] extends skip {
implicit def stringFunc[A] = at[T => A](_ :: HNil)
}
object grabStringFunc extends grabFuncFrom[String]
val filtered = hflist flatMap grabStringFunc