如果我有一个EnumeratorT和一个相应的IterateeT我可以一起运行它们:
val en: EnumeratorT[String, Task] = EnumeratorT.enumList(List("a", "b", "c"))
val it: IterateeT[String, Task, Int] = IterateeT.length
(it &= en).run : Task[Int]
Run Code Online (Sandbox Code Playgroud)
如果枚举器monad比iteratee monad"更大",我可以使用up或者更一般Hoist地"提升"iteratee以匹配:
val en: EnumeratorT[String, Task] = ...
val it: IterateeT[String, Id, Int] = ...
val liftedIt = IterateeT.IterateeTMonadTrans[String].hoist(
implicitly[Task |>=| Id]).apply(it)
(liftedIt &= en).run: Task[Int]
Run Code Online (Sandbox Code Playgroud)
但是,当iteratee monad比枚举器monad"更大"时,我该怎么办?
val en: EnumeratorT[String, Id] = ...
val it: IterateeT[String, Task, Int] = ...
it &= ???
Run Code Online (Sandbox Code Playgroud)
似乎没有任何Hoist实例EnumeratorT,也没有任何明显的"提升"方法.
最近斯卡拉兹引起了我的注意.它看起来很有趣,但我没有找到任何关于图书馆的好介绍.看起来scalaz融合了很多来自haskell和数学的想法.我发现的大多数文章都假设您已经对这些概念感到满意.
我正在寻找的是逐步介绍图书馆和基本概念 - 从简单和基本概念到更高级(基于基础).
我也看了一些例子,但是我很难找到应该开始学习库的地方.
有人可以向我推荐一些好的scalaz介绍或教程(涵盖基础知识和高级概念)吗?或者在答案中给我起点.
谢谢大家的好消息!我总结了所有的答案,并在我的博客中添加了一些链接:
http://hacking-scala.org/post/49050104489/scalaz-resources-for-beginners
对于那些寻找Scalaz API文档的人来说,他们在这里:
http://docs.typelevel.org/api/scalaz/nightly/index.html#package
背景
正如在这个问题中所指出的,我正在使用Scalaz 7迭代器来处理恒定堆空间中的大型(即无界)数据流.
我的代码看起来像这样:
type ErrorOrT[M[+_], A] = EitherT[M, Throwable, A]
type ErrorOr[A] = ErrorOrT[IO, A]
def processChunk(c: Chunk, idx: Long): Result
def process(data: EnumeratorT[Chunk, ErrorOr]): IterateeT[Vector[(Chunk, Long)], ErrorOr, Vector[Result]] =
Iteratee.fold[Vector[(Chunk, Long)], ErrorOr, Vector[Result]](Nil) { (rs, vs) =>
rs ++ vs map {
case (c, i) => processChunk(c, i)
}
} &= (data.zipWithIndex mapE Iteratee.group(P))
Run Code Online (Sandbox Code Playgroud)
问题
我似乎遇到了内存泄漏,但我对Scalaz/FP不太熟悉,不知道这个bug是在Scalaz中还是在我的代码中.直观地说,我希望这段代码只需要(大约为)P倍的Chunk-size空间.
注:我发现了一个类似的问题,其中OutOfMemoryError遇到,但我的代码没有使用consume.
测试
我跑了一些测试试图找出问题.总而言之,只有在使用zipWithIndex和泄漏时才会出现泄漏group.
// no zipping/grouping …Run Code Online (Sandbox Code Playgroud) 当被问及Scala中的依赖注入时,很多答案都指向使用Reader Monad,无论是来自Scalaz还是只是自己编写.有很多非常明确的文章描述了这种方法的基础知识(例如,Runar的演讲,Jason的博客),但我没有设法找到更完整的例子,我没有看到这种方法的优势超过例如更多传统的"手动"DI(参见我写的指南).最有可能的是我错过了一些重要的观点,因此问题就出现了.
举个例子,我们假设我们有这些类:
trait Datastore { def runQuery(query: String): List[String] }
trait EmailServer { def sendEmail(to: String, content: String): Unit }
class FindUsers(datastore: Datastore) {
def inactive(): Unit = ()
}
class UserReminder(findUser: FindUsers, emailServer: EmailServer) {
def emailInactive(): Unit = ()
}
class CustomerRelations(userReminder: UserReminder) {
def retainUsers(): Unit = {}
}
Run Code Online (Sandbox Code Playgroud)
在这里,我使用类和构造函数参数进行建模,这与"传统"DI方法非常相似,但是这个设计有几个好的方面:
UserReminder不知道FindUsers需要数据存储.功能甚至可以在单独的编译单元中IO如果我们想要捕获效果等,"业务逻辑"方法可以返回包含在monad中的值.怎么能用Reader monad建模呢?保留上面的特性会很好,因此很清楚每个功能需要什么样的依赖关系,并隐藏一个功能与另一个功能的依赖关系.请注意,使用classes更多的是实现细节; 也许使用Reader monad的"正确"解决方案会使用其他东西.
我找到了一个有点相关的问题,暗示:
我正在尝试理解如何重新组织一个程序,我之前将其编写为一系列状态转换:
我有一些业务逻辑:
type In = Long
type Count = Int
type Out = Count
type S = Map[Int, Count]
val inputToIn: String => Option[In]
= s => try Some(s.toLong) catch { case _ : Throwable => None }
def transition(in: In): S => (S, Out)
= s => { val n = s.getOrElse(in, 0); (s + (in -> n+1), n+1) }
val ZeroOut: Out = 0
val InitialState: S = Map.empty
Run Code Online (Sandbox Code Playgroud)
有了这些我希望构造一个程序来传递一些初始状态(一个空的Map),从stdin读取输入,将其转换为In,运行状态转换并输出当前状态S和输出Out到 …
我试图向Web服务发出一个简单的POST请求,该请求返回Scala中的一些XML.
似乎Dispatch是用于此任务的标准库,但我找不到它的文档.我在上面链接的主站点详细解释了什么是承诺以及如何进行异步编程,但实际上并没有记录API.有一个周期表 - 看起来有点可怕 - 但它只对那些已经知道该做什么并且只需要提醒隐藏语法的人有用.
似乎Scalaz也有一些HTTP工具,但我也找不到任何文档.
我正试图找到'正确'的演员实现.我意识到有一堆它们,选择一个有点令人困惑.就个人而言,我对远程演员特别感兴趣,但我想完整的概述会对很多人有所帮助.这是一个非常普遍的问题,所以请随意回答您所了解的实施问题.
我知道以下Scala Actor实现(SAI).请添加缺少的.
Scalaz(http://code.google.com/p/scalaz/)
这些SAI的目标用例是什么(轻量级与"重型"企业框架)?
给定一个类型类,其中应根据返回类型执行实例选择:
case class Monoid[A](m0: A) // We only care about the zero here
implicit def s[T] : Monoid[Set[T]] = Monoid(Set.empty[T])
implicit def l[T] : Monoid[List[T]] = Monoid(List.empty[T])
def mzero[A](implicit m: Monoid[A]) : A = m.m0
Run Code Online (Sandbox Code Playgroud)
为什么Scala(2.11.6)无法解析正确的实例:
scala> mzero : List[Int]
<console>:24: error: ambiguous implicit values:
both method s of type [T]=> Monoid[Set[T]]
and method l of type [T]=> Monoid[List[T]]
match expected type Monoid[A]
mzero : List[Int]
^
Run Code Online (Sandbox Code Playgroud)
当它有没有问题,使用时发现基于返回类型的隐式隐函数(我们在这里重新定义它为我来说明它是多么相似mzero)
def i[A](implicit a : A) : …Run Code Online (Sandbox Code Playgroud) scala ×10
scalaz ×10
iterate ×2
actor ×1
akka ×1
enumerator ×1
http ×1
implicit ×1
lift ×1
monads ×1
return-type ×1
scala-cats ×1
state-monad ×1