将Either列表映射到整数

huangapple go评论62阅读模式
英文:

Mapping an Either list to integers

问题

我正在尝试完成以下操作:

processRights :: [Either a Int] -> Int
processRights xs = map (\Right x -> x, \Left x -> 0) xs

所以,xs[Either a Int],我希望生成一个相同长度的映射列表,对于每个 int,都有相同的 int,否则为 0。

我该如何实现这一点?

英文:

I am trying to do the following:

processRights :: [Either a Int] -> Int
processRights xs = map (\Right x -> x, \Left x -> 0) xs

So, xs is a [Either a Int], and I wish to produce a mapped list of the same length where for each int there is the same int, 0 otherwise.

How can I acomplish that?

答案1

得分: 6

你可以使用 eitheridconst 函数:

processRights :: [Either a Int] -> [Int]
processRights = map $ either (const 0) id

either 对于任何 Left 运行第一个函数,对于任何 Right 运行第二个函数。

id 返回其参数。

const 忽略其第二个参数并返回其第一个参数,其预期用途是,例如 const 0 变成一个忽略其参数并只返回 0 的函数。

英文:

You can use the either, id and const functions:

processRights :: [Either a Int] -> [Int]
processRights = map $ either (const 0) id

either runs the first function for any Left, the second function for any Right.

id returns its argument.

const ignores its second argument and returns its first argument, its intended use is that e.g. const 0 becomes a function that ignores its argument and just returns 0.

答案2

得分: 2

以下是翻译好的部分:

你提出的代码实际上非常接近了!以下是一个可以工作的版本,只需要进行最小的更改:

processRights xs = map (\case Right x -> x; Left x -> 0) xs

你需要启用 LambdaCase 语言扩展。(当然,正如其他答案中提到的,还有更符合惯用方式来实现这个效果的方法。)

英文:

Your proposed code is really, really close, actually! Here's a working version with minimal changes:

processRights xs = map (\case Right x -> x; Left x -> 0) xs

You will need to turn on the LambdaCase language extension. (And of course, as mentioned in other answers, there are more idiomatic ways to achieve this effect.)

答案3

得分: 1

A clear way to do this is to work with a helper function. Indeed:

processRights :: [Either a Int] -> [Int]
processRights = map go
    where go (Right x) = x
          go (Left _) = 0

This is not the most concise way, but it shows what is happening. You can simplify this with fromRight :: b -> Either a b -> b where we provide a value to use or a Left x element, and it will thus either select that value, or the value wrapped in the Right data constructor, so:

import Data.Either(fromRight)

processRights :: Num b => [Either a b] -> [b]
processRights = map (fromRight 0)
英文:

A clear way to do this is to work with a helper function. Indeed:

processRights :: [Either a Int] -> [Int]
processRights = map go
    where go (Right x) = x
             (Left _) = 0

This is not the most concise way, but it shows what is happening. You can simplify this with fromRight :: b -> Either a b -> b where we provide a value to use or a Left x element, and it will thus either select that value, or the value wrapped in the Right data constructor, so:

import Data.Either(fromRight)

processRights :: Num b => [Either a b] -> [b]
processRights = map (fromRight 0)

huangapple
  • 本文由 发表于 2023年4月13日 17:48:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/76004017.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定