Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Json 正确使用不相交并集的右侧_Json_Scala_Either_Circe - Fatal编程技术网

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"))) 我正在尝

将右[列表]转换为列表的最佳方式是什么

我将像这样解析一个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")))
我正在尝试摸索
或者
,并实现从上面的列表中获取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)