首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >双函子的参数化型别名

双函子的参数化型别名
EN

Stack Overflow用户
提问于 2016-06-14 12:52:22
回答 1查看 86关注 0票数 0

我有一个Seq[R],我想把它分成一个Tuple2[Seq[E], Seq[S]],在编写这个代码的时候,我想到了这样一个事实:我可以用一个自定义Bifunctor来处理一个seqs元组,并且在练习中试图对它进行编码:

代码语言:javascript
复制
import scalaz.Bifunctor

type MyType[E, S] = (Seq[E], Seq[S])

case class MyVali[E, S](tp: (Seq[E], Seq[S]))(implicit bifunctor: Bifunctor[MyType]) {
  def bimap[C, D](f: (E) => C, g: (S) => D): (Seq[C], Seq[D]) =
    bifunctor.bimap(tp)(f, g)

  def leftMap[C](f: (E) => C): (Seq[C], Seq[S]) =
    bifunctor.leftMap(tp)(f)

  def rightMap[D](g: (S) => D): (Seq[E], Seq[D]) =
    bifunctor.rightMap(tp)(g)

}

val myValBifunctorInstance = new Bifunctor[MyType] {
  override def bimap[A, B, C, D](fab: (Seq[A], Seq[B]))(f: (A) => C, g: (B) => D): (Seq[C], Seq[D]) =
    (fab._1.map(f), fab._2.map(g))
}

MyVali((Seq.empty[String], Seq.empty[Int]))(myValBifunctorInstance).bimap(a => a, b => b)

这很好,但出于某种原因,我不得不声明一个参数化类型别名来进行所有的编译,即type MyType[E, S] = (Seq[E], Seq[S])和我很难理解为什么这样做不起作用:

代码语言:javascript
复制
def myValBimap[E, S] = new Bifunctor[Tuple2[Seq[E], Seq[S]]] {
  override def bimap[A, B, C, D](fab: (A, B))(f: (A) => C, g: (B) => D): (C, D) = ???
}

错误..。(SeqE,SeqS)不接受类型参数,期望:两个 错误def myValBimapE,S=新双函子[Tuple2[SeqE,SeqS]] {

编译器是否创建了一个2类型的挂起(比如嵌套的lambda类型?)当定义了这样的类型别名时?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-06-14 13:43:24

代码语言:javascript
复制
def myValBimap[E, S] = new Bifunctor[Tuple2[Seq[E], Seq[S]]] {  ... }

上面的Tuple2[...]中的Bifunctor不再有两种类型的参数,因为ES都是填充的。

例如,myValBimap[Int, String]试图创建一个Bifunctor[(Seq[Int], Seq[String])],而类型(Seq[Int], Seq[String])显然没有两个类型参数。

你可以写

  • Bifunctor[({ type λ[α, β] = (Seq[α], Seq[β])})#λ]
  • Bifunctor[λ[(α, β) => (Seq[α], Seq[β])]]使用的是那种投影机插件。

如果需要一个额外的类型,那么需要一个带有类型参数的隐式函数,比如:

代码语言:javascript
复制
implicit def myBimap[F[_]: Functor]: Bifunctor[λ[(α, β) => (F[α], F[β])]] = ???

一个更简单的例子是用于断开/ Functor\/,它为左侧使用了一个类型参数:

代码语言:javascript
复制
implicit def functorDisj[L]: Functor[L \/ ?] = ???
implicit def functorDisj[L]: Functor[({ type λ[α] = L \/ α })#λ] = ???

关于您最初的问题:可能可以将您的R映射到E \/ S并使用separate

代码语言:javascript
复制
import scalaz._, Scalaz._

val integers = List.range(1,10)
val stringOrInts: List[String \/ Int] = 
  integers.map(i => if (i % 2 == 0) i.right else i.toString.left)

stringOrInts.separate
// (List[String], List[Int]) = (List(1, 3, 5, 7, 9),List(2, 4, 6, 8))
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37812593

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档