小编bhe*_*her的帖子

Scalaz:在for-understanding和logging中验证

我承认标题不是很明确:抱歉.

假设我有一个理解:

for {v1<-Validation1(input)
     v2<-Validation2(v1)
     v3<-Validation3(v2)
} yield result
Run Code Online (Sandbox Code Playgroud)

验证1,验证2和验证3进行一些检查(例如"年龄> 18")并使用失败/成功; 所以,如果出现问题,for-comprehension就会中止,我会在结果的失败部分找到原因,否则我会在成功部分获得预期的价值.到目前为止,这么好,也没什么难的.

但Validation1,Validation2,Validation3是成功的,如果他们的输入满足一些规则(例如:"那个人可以投票,因为他的年龄大于18岁,他的国籍是法国人").我想要的是跟踪应用的规则,以便能够在最后显示它们.

这显然是日志记录的一个用例.但我在做这件事的路上犹豫不决:

  1. 拥有一个可由任何函数访问的对象"logger"(Validation1,2和3,以及想要显示日志内容的调用者)

  2. 使记录器成为Validation1,2和3的参数

  3. 等待"Scala中的函数编程"相关章节:)

  4. 其他?

谢谢你的建议

编辑于4月10日

所以,假设我想计算函数:x - > 1/sqrt(x)

首先,我通过检查x> 0来计算sqrt(x)然后如果不是零则采用逆.

使用scalaz.Validation,很简单:

val failsquareroot= "Can't take squareroot of negative number"
val successsquareroot= "Squareroot ok"
val failinverse="Can't take inverse of zero"
val successinverse=  "Inverse ok"

def squareroot(x:Double)=if (x < 0) failsquareroot.fail else sqrt(x).success
def inverse(x:Double)= if (x == 0) failinverse.fail else (1/x).success
def resultat(x:Double)= for {
   y <- squareroot(x)
   z<-inverse(y)
} yield z
Run Code Online (Sandbox Code Playgroud)

现在,如果squareroot成功,我想记录字符串successsquaretoot,如果反向sucesses,我想记录字符串successinverse,以便函数resultat积累两个字符串,以防成功

我开始使用ValidationT,因为Yo Eight建议: …

validation logging scalaz

9
推荐指数
1
解决办法
1921
查看次数

将无形可扩展记录传递给函数(续)

考虑到这个问题:将无形可扩展记录传递给函数,Travis的答案显示,将可扩展记录作为参数的每个函数都必须具有隐式选择器作为参数.我想知道如果我们有很多这样的功能,是否可以将这些声明分解.例如:

val w1 = Witness("foo1")
val w2 = Witness("foo2")
val w3 = Witness("foo3")
//Here some "magical" declarations avoiding to declara selectors in fun1, fun2, fun3 below

 def fun1[L <: HList](xs: L) = ... //Access to foo1, foo2, foo3
 def fun2[L <: HList](xs: L) = ... //Access to foo1, foo2, foo3
 def fun3[L <: HList](xs: L) = ... //Access to foo1, foo2, foo3
Run Code Online (Sandbox Code Playgroud)

谢谢

伯努瓦

编辑12月10日

在尝试答案的代码时,会出现两个问题:

  1. 没有告知关于与foo1,foo2,foo3相关的数据的真实类型:因此,像fun1这样的函数不能使用与这些类型相关联的任何方法.例如,即使foo3是Double,它也不能采用它的平方根.
  2. 如果我有打电话( "foo1" - >> "你好")FUN1 ::( "foo2的" - > 1)::( "foo3" …

scala shapeless

8
推荐指数
1
解决办法
1388
查看次数

将无形的可扩展记录传递给函数(永无止境的故事?

我继续研究可扩展记录,如将无形可扩展记录传递给函数(续):提供的解决方案适用于所有参数都包含至少foo1,foo2和foo3的参数; 这可以写:

fun1(("foo1" ->> "hello") :: ("foo2" ->> 1) :: ("foo3" ->> 1.2) :: HNil)
fun1(("foo1" ->> "hello") :: ("foo2" ->> 1) :: ("foo3" ->> 1.2) :: ("foo4" ->> true) :: HNil)
Run Code Online (Sandbox Code Playgroud)

等等

如果我们可以添加第二个函数fun2:

def fun2[L <: HList : HasMyFields](xs: L) = {
  val selectors = implicitly[HasMyFields[L]]
  import selectors._
  xs("foo1").length + xs("foo2") + xs("foo3")
}
Run Code Online (Sandbox Code Playgroud)

到现在为止还挺好.

现在,我们假设我们有一组字段foo1,foo2,...和一组函数fun1,fun2,它们将{foo1,foo2,...}的任何子集组成的记录作为参数.例如,fun1可以将包含foo1和foo3的记录作为参数,但不一定是foo2,fun2会期望至少包含foo4的记录,依此类推.

有没有办法避免声明像HasMyFields这样多的类,因为它们是可能的组合(如果我们有n个字段,则有2**个组合!)?

scala shapeless

6
推荐指数
1
解决办法
607
查看次数

结合2个列表的元素

假设我们有两个列表:

val l1=List("a","b","c")
val l2 = List("1","2","3")
Run Code Online (Sandbox Code Playgroud)

我想要的是:List("a1", "b2", "c3")即将l1的第n个元素与l2的第n个元素相加

实现它的一种方法是:

(l1 zip l2).map (c => {c._1+c._2})
Run Code Online (Sandbox Code Playgroud)

我只是想知道是否可以用Applicative实现它.我试过了 :

(l1 |@| l2) { _+ _ } 
Run Code Online (Sandbox Code Playgroud)

但它提供了所有组合:

List(a1, a2, a3, b1, b2, b3, c1, c2, c3)
Run Code Online (Sandbox Code Playgroud)

任何的想法?

谢谢

伯努瓦

scala scalaz applicative

4
推荐指数
1
解决办法
2710
查看次数

标签 统计

scala ×3

scalaz ×2

shapeless ×2

applicative ×1

logging ×1

validation ×1