加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

在Scala中做一个任意的类作为一个monad实例

发布时间:2020-12-16 09:23:17 所属栏目:安全 来源:网络整理
导读:为了使在monad上下文中可操作的任何东西,如果使用Haskell – 我只需要在给定类型的任何地方添加Monad类的实现.所以我根本没有触摸数据类型定义的源.喜欢(人为的东西) data Z a = MyZLeft a | MyZRight aswap (MyZLeft x) = MyZRight xswap (MyZRight x) = My
为了使在monad上下文中可操作的任何东西,如果使用Haskell – 我只需要在给定类型的任何地方添加Monad类的实现.所以我根本没有触摸数据类型定义的源.喜欢(人为的东西)

data Z a = MyZLeft a | MyZRight a

swap (MyZLeft x) = MyZRight x
swap (MyZRight x) = MyZLeft x

instance Monad Z where
  return a = MyZRight a
  (>>=) x f = case x of
                MyZLeft s -> swap (f s)
                MyZRight s -> swap (f s)

所以我没有触及Z的定义,而是把它当成一个monad

如何在Scala中执行此操作?似乎除了混合一些特征和定义方法map / flatMap / filter / withFilter之外,没有什么办法?

解决方法

看看 scalaz

// You could use implementation in the end of this answer instead of this import
import scalaz._,Scalaz._

sealed trait Z[T]
case class MyZLeft[T](t: T) extends Z[T]
case class MyZRight[T](t: T) extends Z[T]

def swap[T](z: Z[T]) = z match {
  case MyZLeft(t) => MyZRight(t)
  case MyZRight(t) => MyZLeft(t)
}

implicit object ZIsMonad extends Monad[Z] {
  def point[A](a: => A): Z[A] = MyZRight(a)
  def bind[A,B](fa: Z[A])(f: A => Z[B]): Z[B] = fa match {
    case MyZLeft(t) => swap(f(t))
    case MyZRight(t) => swap(f(t))
  }
}

用法:

val z = 1.point[Z]
// Z[Int] = MyZRight(1)

z map { _ + 2 }
// Z[Int] = MyZLeft(3)

z >>= { i => MyZLeft(i + "abc") }
// Z[String] = MyZRight(1abc)

z >>= { i => (i + "abc").point[Z] }
// Z[String] = MyZLeft(1abc)

理解(similar to do-notation):

for {
  i <- z
  j <- (i + 1).point[Z]
  k = i + j
} yield i * j * k
// Z[Int] = MyZRight(6)

另见Scalaz cheatsheet和Learning scalaz.

在scalaz没有魔法 – 你可以实现这个没有scalaz.

相关:Typeclases in Scala & Haskell.

最简单的实现Monad与语法,以防您不想使用scalaz:

import scala.language.higherKinds

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

implicit class MonadPointer[A](a: A) {
  def point[M[_]: Monad] = implicitly[Monad[M]].point(a)
}

implicit class MonadWrapper[M[_]: Monad,A](t: M[A]) {
  private def m = implicitly[Monad[M]]
  def flatMap[B](f: A => M[B]): M[B] = m.bind(t)(f)
  def >>=[B](f: A => M[B]): M[B] = flatMap(f)
  def map[B](f: A => B): M[B] = m.bind(t)(a => m.point(f(a)))
  def flatten[B](implicit f: A => M[B]) = m.bind(t)(f)
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读