簡體   English   中英

將Haskell的Monadic Bind運算符添加到Scala

[英]Adding Haskell's Monadic Bind Operator to Scala

在Haskell中,您可以像這樣使用綁定運算符( >>= ):

repli :: [a] -> [a]
repli xs = xs >>= \x -> [x,x]

*Main> repli [1,2,3]
[1,1,2,2,3,3]

我已經讀過flatMap是Scala的綁定運算符:

def repli [A](xs: List[A]): List[A] =
  xs.flatMap { x => List(x,x) }

scala> repli (List(1,2,3))
res0: List[Int] = List(1, 1, 2, 2, 3, 3)

作為一個教學練習,我正在嘗試為Scala添加對>>=支持:

class MyList[T](list: List[T]) {
  def >>= [U](f: T => List[U]): List[U] = list.flatMap(f)
}
implicit def list2mylist[T](list: List[T]) = new MyList(list)

def repliNew [A](xs: List[A]): List[A] =
  xs >>= { x: A => List(x,x) }

scala> repliNew (List(1,2,3))
res1: List[Int] = List(1, 1, 2, 2, 3, 3)

這非常有效,但僅適用於列表。 我真的想用flatMap方法支持任何類。 什么是最好的方式來解決這個問題?

Scalaz的做法如下:

trait MA[M[_], A] {
  def value: M[A]
  def >>=(f: A => M[B])(implicit m: Monad[M]): M[B] =
    m.bind(value, f)
}

對於所有M[_]A MA[M, A]M[A]MA[M, A]隱式轉換:

implicit def ma[M[_], A](m: => M[A]): MA[M, A] = new MA[M, A] {
  lazy val value = m
}

你只需要一個特質Monad和你關心的每個monad的一個實例:

trait Monad[M[_]] {
  def pure[A](a: => A): M[A]
  def bind[A, B](m: M[A], f: A => M[B]): M[B]
}

如何為flatMap添加隱式類的同義詞?

implicit class BindRich[A,B](fm:{def flatMap(a:A):B}) {
  def >>=(a:A):B = fm.flatMap(a)
}

在范圍內,具有flatMap方法的任何對象也將具有>>=

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM