标签: scalaz

Scalaz7中的`sequence`在哪里?

我正在学习Scalaz,我有一个已经使用Scalaz7的项目.关注这个问题我想使用这个功能

sequence[T](l: List[Option[T]]): Option[List[T]]
Run Code Online (Sandbox Code Playgroud)

(并不是说我自己写的很难).但上述问题提到了Scalaz6.

在Scalaz7中哪里可以找到序列函数?

scala scalaz scalaz7

18
推荐指数
1
解决办法
2573
查看次数

Monads VS期货的应用函子

假设我想从2个远程服务聚合数据,并尽可能快地提供响应:

def loadUser: Future[User]
def loadData: Future[Data]

case class Payload(user: User, data: Data)
Run Code Online (Sandbox Code Playgroud)

我知道这个顺序执行异步任务:

for {
  user <- loadUser
  data <- loadData
} yield Payload(user,data)
Run Code Online (Sandbox Code Playgroud)

虽然这个并行执行它们,因为异步任务在顺序链接之前被触发:

val userF = loadUser
val dataF = loadData
for {
  user <- userF 
  data <- dataF
} yield Payload(user,data)
Run Code Online (Sandbox Code Playgroud)

然而,差异对我来说有点过于含蓄,有些人可能最初没有注意到它.


申请人也解决了这个问题

(loadUser |@| loadData) { Payload(_,_) }
Run Code Online (Sandbox Code Playgroud)

有人可以告诉我在应用程序和monad之间使用什么来执行并行异步计算吗?每种方法的优缺点是什么?

monads scala scalaz applicative scala-cats

18
推荐指数
1
解决办法
1415
查看次数

Scalaz:请求Cokleisli组合的用例

这个问题并不意味着火焰诱饵!可能很明显,我最近一直在关注Scalaz.我试图理解为什么我需要库提供的一些功能.这是一些东西:

import scalaz._
import Scalaz._
type NEL[A] = NonEmptyList[A]
val NEL = NonEmptyList
Run Code Online (Sandbox Code Playgroud)

我在我的函数中放了一些println语句来查看发生了什么(除了:如果我试图避免这样的副作用,我会怎么做?).我的职责是:

val f: NEL[Int] => String    = (l: NEL[Int]) => {println("f: " + l); l.toString |+| "X" }
val g: NEL[String] => BigInt = (l: NEL[String]) => {println("g: " + l);  BigInt(l.map(_.length).sum) }
Run Code Online (Sandbox Code Playgroud)

然后我通过cokleisli将它们组合在一起并传入NEL[Int]

val k = cokleisli(f) =>= cokleisli(g)
println("RES: "  + k( NEL(1, 2, 3) ))
Run Code Online (Sandbox Code Playgroud)

这打印什么?

f: NonEmptyList(1, 2, 3)
f: NonEmptyList(2, 3)
f: NonEmptyList(3) …
Run Code Online (Sandbox Code Playgroud)

functional-programming scala scala-2.8 scalaz

17
推荐指数
2
解决办法
1862
查看次数


结合EitherT和未来

我有一个应用程序,可以对不同的后端系统进行大量调用,并希望使用for-comprehensions来简化后端系统的流程.

我希望结合使用EitherT(scalaz)和Future(scala 2.10),这样我就可以捕获第一个潜在错误(其未来或后端系统问题),并向最终用户返回相应的消息.我已经快速查看了scalaz验证,但是建议捕获第一个错误而不是所有错误都是使用EitherT.

我首先在REPL中尝试一个简单的例子,但是我收到了以下错误

错误:找不到参数F的隐含值:scalaz.Functor [scala.concurrent.Future]

import scala.concurrent._
import scalaz._
import Scalaz._
import ExecutionContext.Implicits.global

type EitherFuture[+A] = EitherT[Future, String, A]

def method1Success : EitherFuture[Int] = {
  println("method 1 success")
  EitherT {
    Future {
      1.right
    }
  }
}

def method2Failure : EitherFuture[Int] = {
  println("method 2 failure")
  EitherT {
    Future {
      "fail".left
    }
  }
}

val m1 = method1Success

// problem
m1.isRight

// problem
def methodChain1 = {
  for {
    a <- method1Success
    b <- method2Failure
  } yield b
}
Run Code Online (Sandbox Code Playgroud)

我仍然是scala和scalaz的新手,所以任何指针都会很棒. …

scala future scalaz for-comprehension scalaz7

17
推荐指数
1
解决办法
5035
查看次数

是否会以更具功能性的方式使用Scala(scalaz)会导致性能/可维护性损失?

我目前正在开发一个小型项目(<10k loc),它主要是纯粹的,但依赖于主要基于迭代器的可变优化和一些用于重载计算的数据结构重用.

我想学习更多功能编程,并希望通过例如将可变计算包装到状态变换器monad等中来获得更多类型安全性.为此目的,存在scalaz库.

问题一

当通过使用所有奇特的功能来大规模地抽象我的计算时,我会介绍我不会摆脱的性能杀手吗?就像我的计算被蒙纳德的膝盖深深地包裹起来一样?

问题二

考虑到Scala的有限类型推断,它是否可行?我目前正在与非常大的类型签名(可能因为我不知道如何正确摆脱它们).我认为更多"功能性"将引入更多这样的锅炉板代码.

放弃

我不是在质疑功能方法是好还是坏.向Haskell提出这个问题毫无意义.我在质疑Scala是否合情合理.

根据要求编辑:我的项目中的大型签名示例

(但这是一个不同的问题)

以下代码描述了对类型参数化输入对象(DiscreteFactorGraph[VariableType, FactorType[VariableType]])的迭代计算.你可以构造一个计算对象createInitialState并对其进行计算advanceState,最后从中提取一些信息marginals.

我希望在计算过程中保留因子图对象的类型(及其参数类型),以便最终的应用程序marginals产生正确的类型DiscreteMarginals[VariableType].我认为目前我只需要在计算类型(即TState)中保留变量类型,因此不使用携带因子类型.但是在不同的地方我甚DiscreteFactorGraph至需要变量的类型,所以我倾向于需要更多的类型信息在未来通过计算.

我很喜欢这部分,我希望有更好的解决方案.目前我有一个非常实用的方法,只有那三个功能.但我必须通过它们链接类型.或者,我可以将它定义为一个类,并使用所有这些类型对类进行参数化,因此我不必为每个方法重复类型参数.

object FloodingBeliefPropagationStepper extends SteppingGraphInferer {
  def marginals[V <: DiscreteVariable, F <: DiscreteFactor[V]](state: FloodingBeliefPropagationStepper.TState[V,F]): DiscreteMarginals[V] =
    BeliefPropagation.marginals(state._1, state._2)

  def advanceState[V <: DiscreteVariable, F <: DiscreteFactor[V]](state: FloodingBeliefPropagationStepper.TState[V,F]): FloodingBeliefPropagationStepper.TState[V,F] = {
    val graph = state._1
    (graph,
      BeliefPropagation.computeFactorMessages(
      graph,
      BeliefPropagation.computeVariableMessages(graph, state._2, graph.variables),
      graph.factors))
  }

  def createInitialState[V <: DiscreteVariable, F <: DiscreteFactor[V]](graph: DiscreteFactorGraph[V, F], …
Run Code Online (Sandbox Code Playgroud)

performance scala scalaz

16
推荐指数
1
解决办法
1122
查看次数

在更复杂的计算中使用scalaz状态

我试图了解如何使用scalaz State执行复杂的有状态计算.这是问题所在:

给定一个List[Int]潜在的除数和一个List[Int]数字,找到一个List[(Int, Int)匹配对(除数,数字),其中允许除数最多匹配一个数.

作为测试:

def findMatches(divs: List[Int], nums: List[Int]): List[(Int, Int)]
Run Code Online (Sandbox Code Playgroud)

并通过以下输入:

findMatches( List(2, 3, 4), List(1, 6, 7, 8, 9) )
Run Code Online (Sandbox Code Playgroud)

我们最多可以获得3场比赛.如果我们规定必须按照遍历列表lr的顺序进行匹配,那么匹配必须是:

List( (2, 6) ,  (3, 9) , (4, 8) )
Run Code Online (Sandbox Code Playgroud)

所以需要通过以下两个测试:

assert(findMatches(List(2, 3, 4), List(1, 6, 7, 8, 9)) == List((2, 6), (3, 9), (4, 8)))
assert(findMatches(List(2, 3, 4), List(1, 6, 7, 8, 11)) == List((2, 6),  (4, 8)))
Run Code Online (Sandbox Code Playgroud)

这是一个迫切的解决方案:

scala> def findMatches(divs: …
Run Code Online (Sandbox Code Playgroud)

functional-programming scala scalaz

16
推荐指数
1
解决办法
574
查看次数

使用上下文边界"消极地"以确保范围内不存在类型类实例

tl; dr:我如何做类似下面的编写代码:

def notFunctor[M[_] : Not[Functor]](m: M[_]) = s"$m is not a functor"
Run Code Online (Sandbox Code Playgroud)

' Not[Functor]',是这里的组成部分.
当'm'提供的不是Functor时,我希望它成功,否则编译器会失败.

解决:跳过问题的其余部分,然后直接回答下面的答案.


我粗略地说,我想要完成的是"负面证据".

伪代码看起来像这样:

// type class for obtaining serialization size in bytes.
trait SizeOf[A] { def sizeOf(a: A): Long }

// type class specialized for types whose size may vary between instances
trait VarSizeOf[A] extends SizeOf[A]

// type class specialized for types whose elements share the same size (e.g. Int)
trait FixedSizeOf[A] extends SizeOf[A] {
  def fixedSize: Long
  def sizeOf(a: A) …
Run Code Online (Sandbox Code Playgroud)

scala implicit typeclass higher-kinded-types scalaz

16
推荐指数
1
解决办法
1146
查看次数

在Scalaz中,Kleisli,ReaderT和Reader是否相同只是巧合

在斯卡拉兹

  • Kleisli[F, A, B]是一个包装A => F[B].
  • ReaderT[F, A, B]- 读者monad变换器 - 只是别名Kleisli[F, A, B].
  • Reader[A, B]monad是ReaderT身份monad 的专长Id:
    type Reader[A, B] = ReaderT[Id, A, B].

难道仅仅是巧合还是有一些更深层次的原因Kleisli,ReaderT以及Reader是同构的Scalaz?

scala scalaz kleisli reader-monad

16
推荐指数
1
解决办法
1484
查看次数

尝试[结果],IO [结果],[错误,结果],我应该在最后使用

我想知道我的方法应该是什么签名,以便我优雅地处理不同类型的失败.

这个问题在某种程度上是我已经在Scala中处理错误的许多问题的总结.你可以在这里找到一些问题:


现在,我理解以下内容:

  • 两者都可以用作可能失败的方法调用的结果包装器
  • 尝试是一个正确的biaised要么失败是一个非致命的例外
  • IO(scalaz)有助于构建处理IO操作的纯方法
  • 所有3个都很容易用于理解
  • 由于不兼容的flatMap方法,所有3个都不容易混合以便理解
  • 在功能性语言中,除非它们是致命的,否则我们通常不会抛出异常
  • 我们应该为真正特殊情况抛出异常.我想这是尝试的方法
  • 创建Throwables具有JVM的性能成本,并不适用于业务流程控制

存储库层

现在请考虑我有一个UserRepository.所述UserRepository存储的用户,并限定了findById方法.可能发生以下故障:

  • 致命的失败(OutOfMemoryError)
  • IO失败,因为数据库不可访问/可读

此外,用户可能会丢失,从而导致Option[User]结果

使用存储库的JDBC实现,可以抛出SQL,非致命异常(约束违规或其他),因此使用Try是有意义的.

当我们处理IO操作时,如果我们想要纯函数,那么IO monad也是有意义的.

所以结果类型可能是:

  • Try[Option[User]]
  • IO[Option[User]]
  • 别的什么?

服务层

现在让我们介绍一个业务层,UserService它提供了一些updateUserName(id,newUserName)使用先前定义findById的存储库的方法.

可能发生以下故障:

  • 所有存储库故障都传播到服务层
  • 业务错误:无法更新不存在的用户的用户名
  • 业务错误:新用户名太短

然后结果类型可以是:

  • Try[Either[BusinessError,User]]
  • IO[Either[BusinessError,User]]
  • 别的什么?

这里的BusinessError不是Throwable,因为它不是一个例外的失败.


使用for-comprehensions

我想继续使用for-comprehensions来组合方法调用.

我们不能轻易地将不同的monad混合起来进行理解,所以我想我的所有操作都应该有一些统一的返回类型吗?

我只是想知道你在现实世界的Scala应用程序中如何成功地在不同类型的故障发生时继续使用for-understanding.

对于现在来说,for-comprehension对我来说很好,使用服务和存储库都可以返回,Either[Error,Result]但是所有不同类型的故障都会融合在一起,并且处理这些故障会变得很糟糕.

您是否定义了不同类型的monad之间的隐式转换,以便能够使用for -reherehension?

你定义自己的monad来处理失败吗?

顺便说一下,我很快就会使用异步IO驱动程序.所以我想我的返回类型可能更复杂:IO[Future[Either[BusinessError,User]]]


任何建议都会受到欢迎,因为我真的不知道该使用什么,而我的应用程序并不花哨:它只是一个API,我应该能够区分可以向客户端显示的业务错误,以及技术错误.我试图找到一个优雅而纯粹的解决方案.

scala either scalaz

15
推荐指数
2
解决办法
2519
查看次数