我有一个正常运行的 Rust 程序,使用实双精度数 ( f64) 作为基础类型,并希望扩展系统,以便它也可以处理复杂值 ( num::complex::Complex64)。
一个(简化示例)函数采用一些配置 struct config,并根据该输入在索引处生成一个潜在值idx:
fn potential(config: &Config, idx: &Index3) -> Result<f64, Error> {
let num = &config.grid.size;
match config.potential {
PotentialType::NoPotential => Ok(0.0),
PotentialType::Cube => {
if (idx.x > num.x / 4 && idx.x <= 3 * num.x / 4) &&
(idx.y > num.y / 4 && idx.y <= 3 * num.y / 4) &&
(idx.z > num.z / 4 && idx.z <= 3 * num.z / 4) …Run Code Online (Sandbox Code Playgroud) 我想将 an 转换Either[A, B]为选项,这样 if Eitheris Leftit is Some[A],如果 it is Rightit is None。
到目前为止我已经想出了
either.swap.map(Some(_)).getOrElse(None)
Run Code Online (Sandbox Code Playgroud)
这有点拗口。
和
either match {
case Left(value) => Some(value)
case Right(_) => None
}
Run Code Online (Sandbox Code Playgroud)
这很好,但理想情况下我想知道是否有更惯用的方法使用方法而不是显式匹配。
我有一个这样的 HOCON 配置:
[
{
name = 1
url = "http://example.com"
},
{
name = 2
url = "http://example2.com"
},
{
name = 3
url = {
A = "http://example3.com"
B = "http://example4.com"
}
}
]
Run Code Online (Sandbox Code Playgroud)
我想用 pureconfig 解析它。我如何表示 URL 可以是字符串或多个 URL 的映射,每个 URL 都有一个键?
我试过这个:
import pureconfig.ConfigSource
import pureconfig.generic.auto.exportReader
case class Site(name: Int, url: Either[String, Map[String, String]])
case class Config(sites: List[Site])
ConfigSource.default.loadOrThrow[Config]
Run Code Online (Sandbox Code Playgroud)
但结果是“预期类型为 OBJECT。改为找到 STRING”。
我知道 pureconfig 支持Option. 我发现没有提到支持Either,这是否意味着它可以用其他东西代替?
我还没有在 Scala 或 Haskell 中找到一个函数可以同时转换/映射Either'sLeft和Rightcase 两个转换函数,即类型为
(A => C, B => D) => Either[C, D]
Run Code Online (Sandbox Code Playgroud)
forEither[A, B]在 Scala 中,或类型
(a -> c, b -> d) -> Either a b -> Either c d
Run Code Online (Sandbox Code Playgroud)
在哈斯克尔。在 Scala 中,它相当于这样调用fold:
(A => C, B => D) => Either[C, D]
Run Code Online (Sandbox Code Playgroud)
或者在 Haskell 中,它相当于这样调用either:
mapLeftOrRight :: (a -> c) -> (b -> d) -> Either a b -> Either c d
mapLeftOrRight fa fb …Run Code Online (Sandbox Code Playgroud) 在我当前的项目中,我使用Either[Result, HandbookModule]( Resultis an HTTP Statuscode) 作为返回类型,以便在出现问题时创建正确的状态。我现在已经将我的数据库访问重构为非阻塞。
此更改要求我的数据库访问函数的返回类型更改为Future[Either[Result, HandbookModule]].
现在我不确定如何将此函数与另一个返回Either[Result, Long].
所以为了更好地说明我的意思:
def moduleDao.getHandbooks(offset, limit): Future[Either[Result, List[Module]] = Future(Right(List(Module(1))))
def nextOffset(offset, limit, results): Either[_, Long] = Right(1)
def getHandbooks(
offset: Long,
limit: Long): Future[Either[Result, (List[HandbookModule], Long)]] = {
for {
results <- moduleDao.getHandbooks(offset, limit)
offset <- nextOffset(offset, limit, results)
} yield (results, offset)
}
Run Code Online (Sandbox Code Playgroud)
在更改之前,这显然没有问题,但我不知道最好的方法是什么。
或者有没有办法将 a 转换Future[Either[A, B]]为 an Either[A, Future[B]]?
我正在尝试执行以下操作:
processRights :: [Either a Int] -> Int
processRights xs = map (\Right x -> x, \Left x -> 0) xs
Run Code Online (Sandbox Code Playgroud)
所以,xs是 a [Either a Int],我希望生成一个相同长度的映射列表,其中每个 int 都有相同的 int,否则为 0。
我怎样才能做到这一点?
我有一个case class包含命令行配置信息的Scala :
case class Config(emailAddress: Option[String],
firstName: Option[String]
lastName: Option[String]
password: Option[String])
Run Code Online (Sandbox Code Playgroud)
我正在编写一个验证函数来检查每个值是否为Some:
def validateConfig(config: Config): Try[Config] = {
if (config.emailAddress.isEmpty) {
Failure(new IllegalArgumentException("Email Address")
} else if (config.firstName.isEmpty) {
Failure(new IllegalArgumentException("First Name")
} else if (config.lastName.isEmpty) {
Failure(new IllegalArgumentException("Last Name")
} else if (config.password.isEmpty) {
Failure(new IllegalArgumentException("Password")
} else {
Success(config)
}
}
Run Code Online (Sandbox Code Playgroud)
但如果我理解来自Haskell的monad,似乎我应该能够将验证链接在一起(伪语法):
def validateConfig(config: Config): Try[Config] = {
config.emailAddress.map(Success(config)).
getOrElse(Failure(new IllegalArgumentException("Email Address")) >>
config.firstName.map(Success(config)).
getOrElse(Failure(new IllegalArgumentException("First Name")) >>
config.lastName.map(Success(config)).
getOrElse(Failure(new IllegalArgumentException("Last Name")) …Run Code Online (Sandbox Code Playgroud) -- | Convert a 'Maybe a' to an equivalent 'Either () a'. Should be inverse
-- to 'eitherUnitToMaybe'.
maybeToEitherUnit :: Maybe a -> Either () a
maybeToEitherUnit a = error "Not yet implemented: maybeToEitherUnit"
-- | Convert a 'Either () a' to an equivalent 'Maybe a'. Should be inverse
-- to 'maybeToEitherUnit'.
eitherUnitToMaybe :: Either () a -> Maybe a
eitherUnitToMaybe = error "Not yet implemented: eitherUnitToMaybe"
-- | Convert a pair of a 'Bool' and an 'a' to 'Either …Run Code Online (Sandbox Code Playgroud) 我需要编写一个程序来解码一个包含四个值的列表,这些值可以是I或O的列表[Either Bool Bool].我知道我必须使用,但我根本无法绕过它.现在我完全绝望,因为我根本无法解决这个问题.
示例输入和输出可能如下所示:[I,O,O,I] => [Left True,Right False]
这是我目前的代码:
module Blueprint where
import Prelude
import Data.Maybe
data Bit = O | I deriving (Eq, Show)
encode :: [Either Bool Bool] -> [Bit]
encode [] = []
encode l = case head l of
Left False -> [I, I] ++ encode (tail l)
Left True -> [I, O] ++ encode (tail l)
Right False -> [O, I] ++ encode (tail l)
Right True -> [O, O] ++ encode (tail …Run Code Online (Sandbox Code Playgroud) 我有两个either值,例如:
Either String Config -- error string or config parsed
Either String Env -- error string or environment variables detected
Run Code Online (Sandbox Code Playgroud)
我想将它们的值提取到此记录中:
type App = App { config :: Config, env :: Env }
Run Code Online (Sandbox Code Playgroud)
如果有错误则快速失败(Left其中一个值的值).
我可以使用两个case语句,但我想知道是否已经有一个我可以在这里使用的抽象?
理想情况下,我会在出错时记录消息并立即退出程序.