将Haskell的Monadic绑定运算符添加到Scala

将Haskell的Monadic绑定运算符添加到Scala

本文介绍了将Haskell的Monadic绑定运算符添加到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,2,2,3,3)

作为教学练习中,我试图增加对>支撑;> = 来的Scala:

  class MyList [T](list:List [T]){
def>> = [U] (F:T =>列表[U]):列表[U] = list.flatMap(F)
}
隐式DEF list2mylist [T](列表:列表[T])=新MYLIST (列表)

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

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

这个功能完美,但仅适用于列表。我真的很想用 flatMap 方法来支持任何类。最好的方法是什么?



 特征MA [M [_],A (隐含m:Monad [M]):M [B] =(f:A => M [B]) 
m.bind(value,f)
}

所有 M [_] M [A] MA [M,A] / code>和 A

 隐式def ma [ M [_],A](m:=> M [A]):MA [M,A] =新MA [M,A] {
懒值值= m
}

您只需要一个特征 Monad 和一个它为你关心的每一个monad:

pre $ $ code $特性Monad [M [_]] {
def pure [A] (A:= A):M [A]
def bind [A,B](m:M [A],f:A => M [B]):M [B]
}


In Haskell, you can use the bind operator (>>=) like this:

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

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

I've read that flatMap is Scala's bind operator:

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)

As a pedagogic exercise, I'm trying to add support for >>= to 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)

This works perfectly, but only for Lists. I really want to support any class with a flatMap method. Whats the best way to go about this?

解决方案

Scalaz does it as follows:

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

With implicit conversions from M[A] to MA[M, A] for all M[_] and A:

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

You just need a trait Monad and an instance of it for every monad you care about:

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

这篇关于将Haskell的Monadic绑定运算符添加到Scala的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-16 07:26