如何显示OK结果

时间:2016-01-24 00:54:44

标签: error-handling elm maybe

我正在玩Elm示例,我注意到field示例提供了Result类型。卡住之后,我想出了这个简化的案例:

import Html exposing (text)
import String

f: Int -> Int
f x = x + 1

g: Result String Int -> Result String Int
g x = (Result.map f) x

main =
  text (  toString ( g  (String.toInt 5 ) ))

结果显示 OK 6 ,我希望它只显示 6 - 我知道toString采用任何类型并返回它的字符串表示。所以也许我可以修改toString

  • 如果结果为OK,那么我可以打印数值结果
  • 如果结果是Err,那么我想做一些自定义错误消息

可能这是andThen的原因,因为+ 1操作可能会失败。

andThen : Result e a -> (a -> Result e b) -> Result e b
andThen result callback =
    case result of
      Ok value -> callback value
      Err msg -> Err msg

andThen 的定义正是它所做的......并且是case的一个实例。

使用andThen或普通case如何修复我的示例?即使我自己修复它,它可能不是具有良好错误处理的最类似Elm的解决方案。所以我发布了这个问题。

1 个答案:

答案 0 :(得分:4)

当一个函数返回一个Result时,你可以选择 - 你也可以返回一个Result,在这种情况下你可以返回Err(某事物)或Ok(某物)。这会将您的错误渗透到调用函数,调用函数可以决定要执行的操作。另一种方法是你可以返回一些不是结果的东西,比如String或Html。如果你走第二条路线,那么你需要处理结果的两种可能性,仍然返回你的String或Html。

因此,例如,此函数获取结果并返回一个字符串。它处理两种可能性,即使结果是Err也返回一个字符串。

foo: Result String Err -> String
foo myres = 
  case myres of 
    Ok(str) -> str
    Err(e) -> "there was an error! uh oh"

这是一个问题,即你希望结果的层次结构有多远。您是否希望错误一直渗透到顶层?也许你的顶级功能是这样的:

View: Model -> Html
View model = 
  case makeMyHtml(model) of 
    Ok(htm) -> htm
    Err(e) -> renderSpecialErrorHtmlPage(e)

无论如何,要摆脱' Ok'在这种情况下,你可以这样做:

main =
  let res = g  (String.toInt 5 ) 
  text (  toString ( Result.withDefault "g returned an error!" res)) 

如果g返回Ok(6),那么你得到" 6",但如果它返回错误,你得到" g返回错误!"。