考虑这段代码(从这里获取并修改为使用字节而不是字符行).
import java.io.{ File, InputStream, BufferedInputStream, FileInputStream }
import scalaz._, Scalaz._, effect._, iteratee.{ Iteratee => I, _ }
import std.list._
object IterateeIOExample {
type ErrorOr[+A] = EitherT[IO, Throwable, A]
def openStream(f: File) = IO(new BufferedInputStream(new FileInputStream(f)))
def readByte(s: InputStream) = IO(Some(s.read()).filter(_ != -1))
def closeStream(s: InputStream) = IO(s.close())
def tryIO[A, B](action: IO[B]) = I.iterateeT[A, ErrorOr, B] {
EitherT(action.catchLeft).map(r => I.sdone(r, I.emptyInput))
}
def enumBuffered(r: => BufferedInputStream) = new EnumeratorT[Int, ErrorOr] {
lazy val reader = r
def apply[A] …Run Code Online (Sandbox Code Playgroud) 有人可以解释现实世界的例子如何在下面的方法工作scalaz.Validation?我的意思是loopSuccess和loopFailure.
来自源代码的片段(scalaz7):
scalaz.Validation:
/** Spin in tail-position on the success value of this validation. */
def loopSuccess[EE >: E, AA >: A, X](success: AA => X \/ Validation[EE, AA], failure: EE => X): X =
Validation.loopSuccess(this, success, failure)
/** Spin in tail-position on the failure value of this validation. */
def loopFailure[EE >: E, AA >: A, X](success: AA => X, failure: EE => X \/ Validation[EE, AA]): X =
Validation.loopFailure(this, success, failure)
Run Code Online (Sandbox Code Playgroud)
伴随对象: …
Semigroup的目的是确保关联性和闭合性monoid的目标是基于Semigroup并提供额外的身份.当我使用| + | semigroup appender,为什么我定义了隐式monoid而不是隐式半群
这是我使用reduceLeft的代码,它不需要初始值
val result1 = List(Staff("John", 36), Staff("Andrew", 30))
val result2 = List(Staff("John", 40), Staff("Danny", 30))
val result3 = List(Staff("Andrew", 30))
val result4: List[Staff] = List()
implicit val staffListSemigroup = new Monoid[List[Staff]] {
override def zero: List[Staff] = Nil
override def append(f1: List[Staff], f2: => List[Staff]): List[Staff] = {
val mapSemigroup = f1.map(t => (t.name, t.numberOfTasks)).toMap |+| f2.map(t => (t.name, t.numberOfTasks)).toMap
mapSemigroup.map(t => Staff(t._1, t._2)).toList
}
}
val result = List(result1, result2, result3, result4).reduceLeft(_ |+| _) …Run Code Online (Sandbox Code Playgroud) 我偶尔会遇到这样的代码:
val things : List[A \/ B] = ???
val (as, bs) : (List[A], List[B]) = ??? //insert something to do this
Run Code Online (Sandbox Code Playgroud)
或者在我目前的情况下我想要 Map[A, B \/ C] => (Map[A, B], Map[A, C])
有没有一种很好的方法在一般情况下F[A \/ B]对F进行适当限制?它看起来有点像Unzip主题的变体.
昨晚在回答这个问题时,我注意到以下几点:
scala> val foo: Option[Set[Int]] = Some(Set(1, 2, 3))
foo: Option[Set[Int]] = Some(Set(1, 2, 3))
scala> import scalaz._, Scalaz._
import scalaz._
import Scalaz._
scala> foo.sequenceU
res0: scala.collection.immutable.Set[Int] = Set(1, 2, 3)
Run Code Online (Sandbox Code Playgroud)
也就是说,如果foo是一组可选的整数,则对它进行排序会返回一组整数.
这不是我最初的预期,因为排序a F[G[A]]应该返回a G[F[A]](假设它F是可遍历的并且G 是一个应用函子).但在这种情况下,Option图层就会消失.
我知道这可能与其中一种超类型Set和Unapply制作sequenceU工作的机器之间的某些交互有关,当我能找到几分钟时,我打算通过这些类型进行处理并写下对正在发生的事情的描述.
这似乎是一个潜在有趣的小谜题,我想我会在这里发布,万一有人可以打败我的答案.
我正在使用Scalaz 7的EitherT来构造混合State和\ /的for-understanding.到现在为止还挺好; 我得到的东西基本上是:
State[MyStateType, MyLeftType \/ MyRightType]
Run Code Online (Sandbox Code Playgroud)
这允许我构建在< - 的左侧有很好变量的for-comprehension.
但我无法弄清楚如何从状态动作中返回元组.单个结果很好 - 在下面的代码中,"val comprehension"正是我想要发生的.
但是当我想要回归一个元组时,事情就会崩溃; "val otherComprehension"不会让我这么做
(a, b) <- comprehension
Run Code Online (Sandbox Code Playgroud)
看起来它希望\ /的左侧是Monoid,我不明白为什么.我错过了什么?
(Scalaz 7 2.0.0-SNAPSHOT,Scala 2.10.2)
object StateProblem {
case class MyStateType
case class MyRightType
case class MyLeftType
type StateWithFixedStateType[+A] = State[MyStateType, A]
type EitherTWithFailureType[F[+_], A] = EitherT[F, MyLeftType, A]
type CombinedStateAndFailure[A] = EitherTWithFailureType[StateWithFixedStateType, A]
def doSomething: CombinedStateAndFailure[MyRightType] = {
val x = State[MyStateType, MyLeftType \/ MyRightType] {
case s => (s, MyRightType().right)
}
EitherT[StateWithFixedStateType, MyLeftType, MyRightType](x)
} …Run Code Online (Sandbox Code Playgroud) 鉴于以下功能:
def foo( a: A ): ValidationNEL[String,Seq[B]] = ...
def bar( b: B ): ValidationNEL[String,C] = ...
Run Code Online (Sandbox Code Playgroud)
我想结合它们来构建一个函数,然后调用foo最终调用bar生成的每个元素Seq,这样得到一个ValidationNEL[String,Seq[C]]:
def fooAndBar( a: A ): ValidationNEL[String,Seq[C]]
Run Code Online (Sandbox Code Playgroud)
Scalaz 7中的文档很短,我找不到任何相关的例子.
我计划在我的Scala代码中开始使用Monadic样式,其中包括线程状态.这是一个结合3个monadic函数的简化示例(并且仅关注副作用)
import scalaz._
import Scalaz._
object MonadTest {
def adder(i: Int) = State[String, Int] ({str: String => (str + i.toString + " ", i) })
val oneTwoThreeMonad = for {
m1 <- adder(1)
m2 <- adder(2)
m3 <- adder(3)
} yield m3
oneTwoThreeMonad("start: ")._1 //String = "start: 1 2 3 "
}
Run Code Online (Sandbox Code Playgroud)
这一切都是不言自明的,并按预期工作.但是对于这种对我来说非常有用的方法,我希望能够将它与Listfor-comprehension 结合起来.这是一些(不工作)代码来显示我的意思:
val list = List(1, 2, 3)
val oneTwoThreeBis = for {
i <- list
mx <- adder(i)
} yield mx
Run Code Online (Sandbox Code Playgroud)
基本上我希望能够基于来自a的参数组合monad List- 运行monadic函数对其中的每个元素 …
我开始时有这样的事情:
def nonEmpty[A] = (msg: String) => (a: Option[A]) => a.toSuccess(msg)
val postal: Option[String] = request.param("postal")
val country: Option[String] = request.param("country")
val params =
(postal |> nonEmpty[String]("no postal" )).toValidationNel |@|
(country |> nonEmpty[String]("no country")).toValidationNel
params { (postal, country) => ... }
Run Code Online (Sandbox Code Playgroud)
现在我认为减少样板以获得更好的可读性并且不必向更多的初级团队成员解释什么.toValidateNel和|@|意思是很好的.第一个想法是,List但最后一行将停止工作,我不得不放弃一些静态安全.所以我看向无形:
import shapeless._; import poly._; import syntax.std.tuple._
val params = (
postal |> nonEmpty[String]("no postal"),
country |> nonEmpty[String]("no country")
)
params.map(_.toValidatioNel).reduce(_ |@| _)
Run Code Online (Sandbox Code Playgroud)
然而,我似乎无法超越这.map(...)一点.我按照#scalaz的建议尝试过:
type Va[+A] = Validation[String, A]
type VaNel[+A] …Run Code Online (Sandbox Code Playgroud)
斯卡拉兹州立大学modify有以下签名:
def modify[S](f: S => S): State[S, Unit]
Run Code Online (Sandbox Code Playgroud)
这允许状态被相同类型的状态替换,当状态包括诸如Record其类型随着添加新字段而改变的无形值时,该状态不能很好地工作.在这种情况下,我们需要的是:
def modify[S, T](f: S => T): State[T, Unit]
Run Code Online (Sandbox Code Playgroud)
什么是使Scalaz的State monad适应无形状态的好方法,以便人们可以使用记录而不是可怕的Map[String, Any]?
例:
case class S[L <: HList](total: Int, scratch: L)
def contrivedAdd[L <: HList](n: Int): State[S[L], Int] =
for {
a <- init
_ <- modify(s => S(s.total + n, ('latestAddend ->> n) :: s.scratch))
r <- get
} yield r.total
Run Code Online (Sandbox Code Playgroud)
更新:
Travis答案的完整代码就在这里.
scala ×10
scalaz ×10
scalaz7 ×10
shapeless ×2
validation ×2
iterate ×1
monads ×1
state-monad ×1
types ×1