Scala 在哪里处理monad故障?
我想知道使用monad编写代码的最佳方法是什么(可选,也可以尝试)。 我的第一印象是,那些单子应该让我写逻辑并忽略错误,然后根据类型结果我会更好地知道发生了什么。 我会举一个例子Scala 在哪里处理monad故障?,scala,haskell,Scala,Haskell,我想知道使用monad编写代码的最佳方法是什么(可选,也可以尝试)。 我的第一印象是,那些单子应该让我写逻辑并忽略错误,然后根据类型结果我会更好地知道发生了什么。 我会举一个例子 val a:Option[Something] = list.get("key") 现在我可以像使用map和flatMap一样操作我的值 在代码末尾,如果我没有,则表示列表没有“键”。 只有当您的逻辑很小时,此工作流才起作用。 但是如果我有很多逻辑,我应该如何编写代码呢 i、 e: 现在,在处理错误时,我将执行以下操
val a:Option[Something] = list.get("key")
现在我可以像使用map和flatMap一样操作我的值在代码末尾,如果我没有,则表示列表没有“键”。 只有当您的逻辑很小时,此工作流才起作用。 但是如果我有很多逻辑,我应该如何编写代码呢 i、 e: 现在,在处理错误时,我将执行以下操作:
processedValueOption match {
case None=> .... // server is not identified
case Some(Failure(e)) => //error to get value from server
case .......
}
实际上,我的类型让我知道代码末尾的错误是什么。
但是当你有大的逻辑时,它会变得非常复杂。
你认为我应该怎么写代码?当我编写逻辑以获得简单类型时,是否应该处理错误?
对于此类情况,这两种方法都是更好的解决方案之一
// Explicit errors
object MyErrors {
trait MyError
object ServerNotIdentifiedError extends MyError
object CanNotGetValueFromServerError extends MyError
object ValueProcessingFailedError extends MyError
}
val server: Either[ Server, MyError ] = serverList.get("serverId").match {
case Some( server ) => Left( server )
case None => Right( ServerNotIdentifiedError )
}
// assuming getDataFromServer returns Try[ Value ]
val value:Either[ Value, MyError ] = getDataFromServer( serverId ) match {
case Success( value ) => Left( value ),
case Failure( ex ) => {
ex.printStackTrace();
Right( CanNotGetValueFromServerError )
}
}
// assuming processValue returns Try[ OtherValue ]
val processedValue: Either[ OtherValue, MyError ] = value match {
case Left( value ) => processValue(value) match {
case Success( otherValue ) => Left( otherValue )
case Failure( ex ) => {
ex.printStackTrace()
Right( ValueProcessingFailedError )
}
}
case _ => value
}
在Haskell中,这通常是通过或EitherT或ExceptT
来实现的(EitherT和ExceptT
是单变量变压器,几乎相同)。您可以将do
符号与这些符号中的任何一个一起使用,将可能失败的操作串在一起,并获得最终结果或有关失败的信息。在某些情况下,使用Applicative
操作符可以更好。比如说,
f <$> e1 <*> e2 <*> e3
检查Haskell“errors”包可能很有价值:。通常你也应该用flatMap替换对map的调用。如果你使用flatMap,你不知道错误是什么,例如list1.get(key1).flatMap(key=>list2.get(key))。如果没有,你不知道为什么没有,是因为list1还是list2吗?如果你能给我完整的例子,那就太好了!我很高兴看到这一点。它还可以让我了解为什么以及在哪里使用Applicativegood思想,但我想你已经被惯例、左代表错误、右代表成功所迷惑了是的。。。惯例。。。我们应该遵循惯例。。。但我喜欢做相反的事情,因为印度的道路是左侧行驶的,所以对我来说右侧感觉像是错误的道路。
f <$> e1 <*> e2 <*> e3
f <$> e1 <*> (e2 <|> e3)