我在寻找它利用单子(和类群可能)更广泛的解决方案,实现同
if( xs.contains(None) ) None else Some(xs.flatten)做的xs类型Seq[Option[A]].
我怎么能用Scalaz做到这一点?我觉得我错过了一些明显的东西.
我在项目中使用scalaz7,有时我会遇到导入问题.最简单的方法是开始
import scalaz._
import Scalaz._
Run Code Online (Sandbox Code Playgroud)
但有时这会导致冲突.到目前为止我一直在做的事情是下面一个有点痛苦的过程:
-Xprint:typer以找出隐式解析后代码的外观虽然这有效,但我想简化它.我看到scalaz7有更多细粒度的导入,但我不完全了解它们的组织方式.例如,我看到一个人可以做到
import scalaz.std.option._
import scalaz.std.AllInstances._
import scalaz.std.AllFunctions._
import scalaz.syntax.monad._
import scalaz.syntax.all._
import scalaz.syntax.std.boolean._
import scalaz.syntax.std.all._
Run Code Online (Sandbox Code Playgroud)
等等.
这些子进口是如何组织的?
举个例子,假设我想使用验证.我需要什么,例如注入验证含义并进行以下编译?
3.fail[String]
Run Code Online (Sandbox Code Playgroud)
如何制作ValidationNEL[A, B]一个实例Applicative?
在Scala中,为了读取文本文件并将其上传到数组中,常见的方法是
scala.io.Source.fromFile("file.txt").getLines.toArray
Run Code Online (Sandbox Code Playgroud)
特别是对于非常大的文件,是否有更快的方法可能首先将字节块读入内存然后用新行字符拆分它们?(有关常用方法,请参阅Scala中的读取整个文件.)
非常感谢.
学习Scalaz 6时,我正在尝试编写类型安全的读者返回验证.这是我的新类型:
type ValidReader[S,X] = (S) => Validation[NonEmptyList[String],X]
type MapReader[X] = ValidReader[Map[String,String],X]
Run Code Online (Sandbox Code Playgroud)
我有两个函数为int和字符串(*)创建地图阅读器:
def readInt( k: String ): MapReader[Int] = ...
def readString( k: String ): MapReader[String] = ...
Run Code Online (Sandbox Code Playgroud)
给出以下地图:
val data = Map( "name" -> "Paul", "age" -> "8" )
Run Code Online (Sandbox Code Playgroud)
我可以写两个读者来检索姓名和年龄:
val name = readString( "name" )
val age = readInt( "age" )
println( name(data) ) //=> Success("Paul")
println( age(data) ) //=> Success(8)
Run Code Online (Sandbox Code Playgroud)
一切正常,但现在我想组成两个读者来构建一个Boy实例:
case class Boy( name: String, age: Int )
Run Code Online (Sandbox Code Playgroud)
我最好的看法是:
val boy …Run Code Online (Sandbox Code Playgroud) 考虑这段代码(从这里获取并修改为使用字节而不是字符行).
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) 我有以下代码使用Readermonad进行配置,还必须处理,IO[Option[String]]我最终得到的代码是我的encode函数中的阶梯.
我怎样才能为我的函数中的monad变换器制定Reader并OptionT避免丑陋的嵌套for理解encode?
def encode(fileName: String): Reader[Config, IO[Unit]] = for {
ffmpegWrapper <- findFfmpegWrapper
ffmpegBin <- findFfmpeg
} yield (for {
w <- ffmpegWrapper
b <- ffmpegBin
stream <- callFfmpeg(getCommand(w, b, fileName)).liftM[OptionT]
} yield stream) map (_ foreach (println)) getOrElse Unit.box {}
def getCommand(ffmpegWrapper: String, ffmpegBin: String,
videoFile: String) = s"$ffmpegWrapper $ffmpegBin $videoFile '-vcodec libx264 -s 1024x576' /tmp/out.mp4"
def callFfmpeg(command: String): IO[Stream[String]] = IO {
Process(command).lines_!
} …Run Code Online (Sandbox Code Playgroud) 我有一个看起来像这样的函数:
def emulate: (Cpu => Cpu) => (Cpu => Cpu) = render => {
handleOpcode andThen
handleTimers andThen
handleInput andThen
debug andThen
render
}
Run Code Online (Sandbox Code Playgroud)
我想多次调用handleOpcode函数(比如说10次).在Haskell中,我可能会写一个这样的函数:
ntimes n f = foldr (.) id (replicate n f)
Run Code Online (Sandbox Code Playgroud)
但在Scala中,我不确定如何写它.我试过了:
def nTimes(n: Int, f: => Any) = {
val l = List.fill(n)(f)
l.foldRight(identity[Function]){ (x, y) => y.andThen(x) }
}
Run Code Online (Sandbox Code Playgroud)
但类型都错了.
有没有一种简单的方法来实现这一目标?理想情况下,无需创建自己的功能.也许是斯卡拉兹的东西?
我试图通过移植Dan Piponi本教程中的一些例子来了解Scala中的Monad Transformers:http: //blog.sigfpe.com/2006/05/grok-haskell-monad-transformers.html
我做了几件简单的事:
import Control.Monad.State
import Control.Monad.Identity
test1 = do
a <- get
modify (+1)
b <- get
return (a,b)
test2 = do
a <- get
modify (++"1")
b <- get
return (a,b)
go1 = evalState test1 0
go2 = evalState test2 "0"
Run Code Online (Sandbox Code Playgroud)
变为:
import scalaz._, Scalaz._
val test1 = for {
a <- get[Int]
_ <- modify[Int](1+)
b <- get
} yield (a,b)
val test2 = for {
a <- get[String]
_ <- modify[String](_ + …Run Code Online (Sandbox Code Playgroud) 几个星期前,Dragisa Krsmanovic 在这里问了一个关于如何在Scalaz 7中使用免费monad来避免堆栈溢出的问题(我已经调整了他的代码):
import scalaz._, Scalaz._
def setS(i: Int): State[List[Int], Unit] = modify(i :: _)
val s = (1 to 100000).foldLeft(state[List[Int], Unit](())) {
case (st, i) => st.flatMap(_ => setS(i))
}
s(Nil)
Run Code Online (Sandbox Code Playgroud)
我认为只是举起一个蹦床StateT应该工作:
import Free.Trampoline
val s = (1 to 100000).foldLeft(state[List[Int], Unit](()).lift[Trampoline]) {
case (st, i) => st.flatMap(_ => setS(i).lift[Trampoline])
}
s(Nil).run
Run Code Online (Sandbox Code Playgroud)
但它仍然打击堆栈,所以我只是将其作为评论发布.
Dave Stevens刚刚指出用应用程序*>而不是monadic 进行排序flatMap实际上运行得很好:
val s = (1 to 100000).foldLeft(state[List[Int], Unit](()).lift[Trampoline]) {
case …Run Code Online (Sandbox Code Playgroud) 我正在阅读这篇关于使用Reader monad进行scala依赖注入的精彩文章.
原始示例运行良好,但我对返回类型做了一点改动UserRepository.get/find.是的User,但我把它改成了Try[User].
然后代码将不会编译,我已经多次尝试,但仍然没有幸运.
import scala.util.Try
import scalaz.Reader
case class User(email: String, supervisorId: Int, firstName: String, lastName: String)
trait UserRepository {
def get(id: Int): Try[User]
def find(username: String): Try[User]
}
trait Users {
def getUser(id: Int) = Reader((userRepository: UserRepository) =>
userRepository.get(id)
)
def findUser(username: String) = Reader((userRepository: UserRepository) =>
userRepository.find(username)
)
}
object UserInfo extends Users {
def userEmail(id: Int) = {
getUser(id) map (ut => ut.map(_.email))
}
def userInfo(username: String) = …Run Code Online (Sandbox Code Playgroud) scala ×10
scalaz ×10
monads ×2
scalaz7 ×2
applicative ×1
file ×1
free-monad ×1
haskell ×1
io ×1
iterate ×1
reader-monad ×1
state-monad ×1
trampolines ×1
validation ×1