2016-01-24 3 views
4

Я играю с примерами Elm, и я заметил, что пример field дает Result. После того, как застрял, я придумал этот упрощенный случай:Как отобразить результаты OK

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 принимает любой тип и возвращает строку representaton из Это. Так что, может быть, я могу изменить 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 как исправить мой пример? Даже если я исправлю это самостоятельно, это может быть не самое вялое решение с хорошей обработкой ошибок. Поэтому я отправляю вопрос.

ответ

4

Когда функция возвращает результат, у вас есть выбор - вы также можете вернуть результат, в этом случае вы можете вернуть Err (что-то) или Ok (что-то). Это переносит ваши ошибки до вызывающей функции, которая может решить, что делать. Другой способ - вы можете вернуть то, что не является результатом, например String или Html. Если вы идете по этому второму маршруту, вам нужно обрабатывать обе возможности результата и , но верните свою строку или 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)) 

Если г возвращает Ok (6) то вы получите «6», но если он вернет ошибку, вы получите «g возвратил ошибку!».

Смежные вопросы