Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List 过滤器在shapeless、Scala中的使用_List_Scala_Filter_Shapeless_Heterogeneous - Fatal编程技术网

List 过滤器在shapeless、Scala中的使用

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

可以很容易地按类型在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

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