Json 正确使用不相交并集的右侧
将右[列表]转换为列表的最佳方式是什么 我将像这样解析一个Json字符串Json 正确使用不相交并集的右侧,json,scala,either,circe,Json,Scala,Either,Circe,将右[列表]转换为列表的最佳方式是什么 我将像这样解析一个Json字符串 val parsed_states = io.circe.parser.decode[List[List[String]]](source) 这将创造一个与此相当的价值 val example_data = Right(List(List("NAME", "state"), List("Alabama", "01"), List("Alaska", "02"), List("Arizona", "04"))) 我正在尝
val parsed_states = io.circe.parser.decode[List[List[String]]](source)
这将创造一个与此相当的价值
val example_data = Right(List(List("NAME", "state"), List("Alabama", "01"), List("Alaska", "02"), List("Arizona", "04")))
我正在尝试摸索右
,左
,或者
,并实现从上面的列表中获取StateName和StateValue对列表的最佳方法
我发现这些方法中的任何一种都能满足我的需要(同时删除标题):
诀窍在于不从
或
中获取状态名称/状态值对。它们应该放在里面。如果愿意,您可以将或类型转换为其他类型(例如,通过丢弃左侧可能有的内容,将选项
),但不要破坏效果。应该有东西表明解码可能失败;它可以是或,选项
,尝试
,等等。最终您将相应地处理左右案例,但这应该尽可能晚
让我们举一个简单的例子:
val x: Either[String, Int] = Right(42)
def f(i: Int) = i + 1
您可能会争辩说,您需要从右侧
中取出42,以便将其传递给f
。但这是不对的。让我们重写这个例子:
val x: Either[String, Int] = someFunction()
现在怎么办?我们不知道在值x
中是有左
还是右
,所以我们无法“取出它”。如果是左
,您将获得哪个整数?(如果在这种情况下确实要使用整数值,那就足够了,稍后我将讨论该用例)
相反,您需要做的是保持效果(在本例中为或),并且您需要在该效果的上下文中继续工作。这是为了表明您的程序(在本例中为someFunction()
,或在原始问题中解码)中存在可能出错的点
因此,如果你想将f
应用于你的潜在整数,你需要映射它的效果(我们可以这样做,因为或者都是一个函子,但这个细节可能超出了这个答案的范围):
及
然后,在计算链的最末端,您可以处理左
和右
情况;例如,如果您正在处理一个HTTP请求,那么在Left
的情况下,您可能会返回一个500,而在Right
的情况下,您可能会返回一个200
要使用前面提到的默认值处理用例-如果您真的想这样做,请去掉左
,在这种情况下解析为某个值(例如0),然后您可以使用折叠
:
def f(i: Int) = i + 1
// if x = Left, then z = 0
// if x = Right, then z = x + 1
val z = x.fold(_ => 0, i => i + 1)
诀窍在于不从或
中获取状态名称/状态值对。它们应该放在里面。如果愿意,您可以将或类型转换为其他类型(例如,通过丢弃左侧可能有的内容,将选项
),但不要破坏效果。应该有东西表明解码可能失败;它可以是或,选项
,尝试
,等等。最终您将相应地处理左右案例,但这应该尽可能晚
让我们举一个简单的例子:
val x: Either[String, Int] = Right(42)
def f(i: Int) = i + 1
您可能会争辩说,您需要从右侧
中取出42,以便将其传递给f
。但这是不对的。让我们重写这个例子:
val x: Either[String, Int] = someFunction()
现在怎么办?我们不知道在值x
中是有左
还是右
,所以我们无法“取出它”。如果是左
,您将获得哪个整数?(如果在这种情况下确实要使用整数值,那就足够了,稍后我将讨论该用例)
相反,您需要做的是保持效果(在本例中为或),并且您需要在该效果的上下文中继续工作。这是为了表明您的程序(在本例中为someFunction()
,或在原始问题中解码)中存在可能出错的点
因此,如果你想将f
应用于你的潜在整数,你需要映射它的效果(我们可以这样做,因为或者都是一个函子,但这个细节可能超出了这个答案的范围):
及
然后,在计算链的最末端,您可以处理左
和右
情况;例如,如果您正在处理一个HTTP请求,那么在Left
的情况下,您可能会返回一个500,而在Right
的情况下,您可能会返回一个200
要使用前面提到的默认值处理用例-如果您真的想这样做,请去掉左
,在这种情况下解析为某个值(例如0),然后您可以使用折叠
:
def f(i: Int) = i + 1
// if x = Left, then z = 0
// if x = Right, then z = x + 1
val z = x.fold(_ => 0, i => i + 1)
我觉得这非常有用。非常感谢。我想通过将这一点应用到我的原始示例中来填补空白。类似这样的事情我想(我不知道如何传递异常错误)@wile-e-quixote你明白了主要思想,你正在努力完成最后一步-如何处理左侧的。这是正常的,因为这一步确实很难;想想幸福的道路总是比较容易的。在Java中,通常的做法是抛出一个异常,让调用方担心它,但由于许多原因,这是不好的。在FP中,你尽可能长时间地保持效果。@wile-e-quixote注意到你可以将一种效果转化为另一种效果。例如,在大多数web框架(Play、finch、http4s等)中处理HTTP请求需要您最终返回一个异步效果,如Future或scalaz/monix任务或cats IO等,其余的由框架处理(您不需要自己从效果中“解包”)。因此,如果您正在编写一个计算HTTP响应的函数,那么您可以将其转换为
def f(i: Int) = i + 1
// if x = Left, then z = 0
// if x = Right, then z = x + 1
val z = x.fold(_ => 0, i => i + 1)