标签: either

在Haskell中使用'Either'

我有两个值,t1并且t2,类型的Either String Type.该Left-value用于错误处理.这些值用于返回的函数中Either String Type.

我想要做的是检查是否都t1t2Right-值和满足p :: Type -> Bool.如果他们这样做,我想回来Right (the type inside t1).如果这两个t1t2Right-值,但不能满足p,我要回Left someString.如果其中一个t1或是t2一个Left值,我只想传递该值.

我怎样才能以优雅的方式做到这一点?我有一种预感,使用Either作为monad是正确的做法,但我不确定如何去做.

monads haskell either

6
推荐指数
2
解决办法
6844
查看次数

是否可以在monadic序列中更改monad类型?

我知道可以更改包装类型,以便您可以拥有

f :: (a -> m b)
g :: (b -> m c)
f >>= g :: (a -> m c)
Run Code Online (Sandbox Code Playgroud)

但是有可能改变m吗?如果mMonadError,由一个实现既Either ErrorAEither ErrorB,可不知何故,我把它们连?显然我不能直接链接它们,因为它的类型是Left什么?但是,我遇到的情况是我最后show都要打电话,但我找不到更好的解决方案

case mightFail1 of
  Left e -> show e
  Right v -> either show doStuff mightFail2
Run Code Online (Sandbox Code Playgroud)

在没有我必须明确检查的情况下,它无法正确使用在第一个错误处停止的monadic行为.

monads haskell either

6
推荐指数
2
解决办法
737
查看次数

使用EitherT累积错误

我有一个Web API的小型小样本应用程序,它采用了一个巨大的JSON文档,并且应该分解它并报告每个部分的错误消息.

下面的代码是使用EitherT(和错误包)的一个工作示例.但是,问题是EitherT在遇到的第一个Left上打破了计算,只返回它看到的第一个"错误".我想要的是一个错误消息列表,所有可能产生的消息.例如,如果第一行runEitherT失败,那么就没有什么可以做的了.但是如果第二行失败,那么我们仍然可以尝试运行后续行,因为它们对第二行没有数据依赖性.因此,理论上我们可以一次性生成更多(不一定是所有)错误消息.

是否可以懒惰地运行所有计算并返回我们可以找到的所有错误消息?

{-# LANGUAGE OverloadedStrings #-}

module Main where

import Data.ByteString.Lazy.Char8 (pack)
import Web.Scotty as S
import Network.Wai.Middleware.RequestLogger
import Data.Aeson
import Data.Aeson.Types
import Control.Lens hiding ((.=), (??))
import Data.Aeson.Lens
import qualified Data.Text as T
import Control.Error
import Control.Applicative
import qualified Data.HashMap.Strict as H
import Network.HTTP.Types

data TypeOne = TypeOne T.Text TypeTwo TypeThree
  deriving (Show)

data TypeTwo = TypeTwo Double
  deriving (Show)

data TypeThree = TypeThree Double
  deriving (Show)

main :: IO () …
Run Code Online (Sandbox Code Playgroud)

error-handling haskell either

6
推荐指数
1
解决办法
788
查看次数

为什么Either派生出Show但是Maybe不会?

两者的文档EitherMaybe表明他们有实例Show.

Either被定义为派生Show,简单地说:

data  Either a b  =  Left a | Right b
  deriving (Eq, Ord, Read, Show, Typeable)
Run Code Online (Sandbox Code Playgroud)

然而,Maybe不是:

data  Maybe a  =  Nothing | Just a
  deriving (Eq, Ord)
Run Code Online (Sandbox Code Playgroud)

既然它们是一部分base并且如此相似,为什么不Maybe直接导出Show

另一个问题也可能是,它在哪里得到它的Show实例?

haskell show either maybe deriving

6
推荐指数
1
解决办法
246
查看次数

未来[List [Error\/ Double]]到Scala中的Future [[List [Error]\/ List [Double]]

我正在玩Scala(z)学习功能编程.

我有一个类型的值,Future[List[Error \/ Double]]并希望将其转换为类型的东西Future[[List[Error] \/ List[Double]].

目标是对左派和权利进行分组.

我目前有以下内容:

val foo: Future[List[Error] \/ List[Double]] = {
  for {
    results <- resultsF
  } yield
    results.foldLeft(\/[List[Error], List[Double]])({
      case (acc, v) if v.isRight => v :: \/-(acc)
      case (acc, v) if v.isLeft => v :: -\/(acc)
    })
}
Run Code Online (Sandbox Code Playgroud)

但是,我得到一个错误,::这是因为我的累加器不是一个列表(来自外部)\/[List[Error], List[Double]].应该怎么做?

scala list either scalaz

6
推荐指数
1
解决办法
124
查看次数

C#FP:验证和执行错误处理功能方式 - 改进空间?

我是C#中功能性思维方式的新手(嗯......不仅限于语言).让我们说有方法:

T LoadRecord<T>(int id)
Run Code Online (Sandbox Code Playgroud)

概念

1.验证

当给出无效输入时,我应该返回类似的内容Either<IEnumerable<ValidationError>, T>.

2.执行

当调用可能抛出的DB/API/...时,我应该返回Either<Exception, T>.

3.一些或没有记录

因为入境可能存在,也可能不存在,我正在回归Option<T>.

最终签名

如果你将上述所有内容结合起来,你最终会得到:

Either<IEnumerable<ValidationError>, Either<Exception, Option<T>> LoadRecord<T>(int id)
Run Code Online (Sandbox Code Playgroud)

我可以介绍如下类型:

  • Validation<T>(〜: Either<IEnumerable<ValidationError>, T>)
  • Result<T>(〜: Either<Exception, T>)

现在,我的方法的签名看起来像:

Validation<Result<Option<T>>> LoadRecord<T>(int id)
Run Code Online (Sandbox Code Playgroud)

用法

return LoadRecord<User>(1).Match(
           vl => BadRequest(),
           vr => vr.Match(
                     el => StatusCode(500),
                     er => er.Some(u => Ok(u))
                             .None(NotFound());
Run Code Online (Sandbox Code Playgroud)

势在必行的实施

try
{
    var u = LoadRecord<User>(id);
    if (u == null)
    {
        return NotFound();
    }

    return Ok(u);
}
catch …
Run Code Online (Sandbox Code Playgroud)

c# functional-programming optional either

6
推荐指数
1
解决办法
163
查看次数

如何初始化“向右”中的一个并指定“左”的类型?

我想初始化一个Eitherto Left,但这需要指定边的类型Right(反之亦然)。

如果我不这样做,则默认情况下将Right一侧键入Nothing,以便执行以下操作:

List(5, 42, 7).foldLeft(Left("empty")) {
  case (Left(_), i)  => Right(i)
  case (Right(s), i) => Right(s + i)
}
error: type mismatch;
    found   : scala.util.Right[Nothing,Int]
    required: scala.util.Left[String,Nothing]
Run Code Online (Sandbox Code Playgroud)

我显然被迫冗长地提供的两面类型Either

List(5, 42, 7).foldLeft(Left("empty"): Either[String, Int]) {
  case (Left(_), i)  => Right(i)
  case (Right(s), i) => Right(s + i)
}
Run Code Online (Sandbox Code Playgroud)

以类似的方式,我可以使用Option.empty[Int]初始化NoneOption[Int],是否可以将初始化Left("smthg")Either[String, Int]

scala either

6
推荐指数
2
解决办法
99
查看次数

如何避免案件金字塔?

我的代码结构如下例所示。我很确定应该有一种方法可以更合理地构建它。我认为 Either (or Error) monad 可以提供帮助,但我不知道从哪里开始。有什么指示可以让我朝着正确的方向前进吗?

data Data1 = Data1 { d2Id :: String }
data Data2 = Data2 { d3Id :: String }
data Data3 = Data3 { d4Id :: String }

getData1 :: String -> IO (Either String Data1)
getData2 :: String -> IO (Either String Data2)
getData3 :: String -> IO (Either String Data3)

process :: Data1 -> Data2 -> Data3 -> IO ()

get :: String -> IO ()
get id = do
  r1 <- getData1 …
Run Code Online (Sandbox Code Playgroud)

haskell either

5
推荐指数
1
解决办法
227
查看次数

具有保留类型的 Either 到 Either of 序列的通用序列

我想要一个将任何可迭代类型转换为C[_]Either[A, B]函数Either[C[A], C[B]]

我让它工作了,但我使用了asInstanceOf方法,我觉得这种方法在某些情况下可能会失败(我还不知道那会是什么场景,因为我不太了解CanBuildFrom解决)。

我认为我应该使用自定义来实现它CanBuildFrom,但我希望有更简单的方法来做到这一点。

这是我的方法:

type IterableCollection[A[_], B] = A[B] with Iterable[B]

implicit class IterableEither[C[_], A, B](self: IterableCollection[C, Either[A, B]]) {
  def accumulate: Either[IterableCollection[C, A], IterableCollection[C, B]] = {
    val failures = self.collect { case x @ Left(_) => x.value }.asInstanceOf[IterableCollection[C, A]]

    if (failures.nonEmpty) Left(failures)
    else Right(self.collect { case x @ Right(_) => x.value }.asInstanceOf[IterableCollection[C, B]])
  }
}
Run Code Online (Sandbox Code Playgroud)

我已经用 Scala 编程有一段时间了,但从未依赖过asInstanceOf,因此我有点害怕将这种代码引入生产环境。你们有没有想到一种无需演员就能做到这一点的方法?

scala either scala-collections

5
推荐指数
2
解决办法
883
查看次数

在scala中正确使用Either,Try和Exception / ControlThrowable

在我的Scala代码(库以及应用程序)我目前使用的混合OptionTry,当任一两个感觉更apropriate。

我倾向于实现“ doSomething”方法,该方法可以在返回值成功或在失败时成功Try。也就是说,它们可以包含引发的代码,或者当我“手动”检测到错误时,人为地创建a Throwable并返回a Failure。这些方法的返回值因此为Try[ReturnType]

现在,我读到创建异常在某种程度上不是最优的,因为它创建了堆栈跟踪(因此很慢),而我什至不需要。我还看到了使用的子类的示例ControlThrowable,这些示例不会创建堆栈跟踪,但是它们也没有消息,Try当然也不会捕获它。

现在我的具体问题是,我一般都主张EitherTry,当我想要做的运行时错误处理/方法的返回值,并使用Try在那里我真正需要的情况下,只能东西(如第三方代码)?
这样,我就不必创建笨拙的Throwables,而只需使用例如字符串in Left来产生错误。

所以基本上:

  • Option:日常使用的东西是否具有价值
  • Try:在方法内捕获异常,但不用作返回值
  • Either:通用返回值,包含错误(字符串)或成功值

这个概念行得通吗,还是有一种更可行/更通用的方法?

error-handling scala exception-handling try-catch either

5
推荐指数
1
解决办法
400
查看次数