【问题标题】:Elm: Access value of custom typeElm:自定义类型的访问值
【发布时间】:2020-04-21 19:39:44
【问题描述】:

我在 Elm 中有一个自定义类型来处理错误分支。基本上,我有一个输入,它给出了Strings,我需要将它转换为Ints。

type Seconds
    = Error Int
    | Valid Int

type alias Model =
    { timeBetweenExercises : Seconds
    , roundsSequenceOne : Seconds
    , roundsSequenceTwo : Seconds
    , roundsSequenceThree : Seconds
    , repititionsPerExercise : Seconds
    , secondsPerExercise : Seconds
    , totalTrainingDuration : Seconds
    }


init : Model
init =
    { timeBetweenExercises = Valid 3
    , roundsSequenceOne = Valid 3
    , roundsSequenceTwo = Valid 3
    , roundsSequenceThree = Valid 3
    , repetitionsPerExercise = Valid 6
    , secondsPerExercise = Valid 6
    , totalTrainingDuration = Valid 6
    }

我从Evan's "Life of a file" talk 得到了自定义类型的想法。我想在出现错误时记住数字(例如,用户输入了字符串而不是数字)。这是我的更新功能的尝试:

update : Msg -> Model -> Model
update msg model =
    case msg of
        TimeBetweenExercisesChanged newTime ->
            case String.toInt newTime of
                Nothing ->
                    { model | timeBetweenExercises = Error model.timeBetweenExercises }

                Just time ->
                    { model | timeBetweenExercises = Valid time }

我的问题是,编译器对我大喊大叫是因为 model.timeBetweenExercises 的类型是 Seconds。有没有办法只能获取自定义类型的Int值?

【问题讨论】:

  • 我会说类型错误很清楚,但我不能说如何解决它,因为我不明白你想要做什么。我猜您只是想在 Nothing 案例中保持模型不变?我当然看不出你还能做些什么——但正如我所说,我真的不知道你的目标是什么。

标签: elm


【解决方案1】:

在我看来,模型是错误的,原因有两个:

  1. 如果您有一个在所有情况下都通用的值,则将其移出并上一级通常会更方便。

  2. 您的更新函数表明Error 状态实际上并没有描述它所持有的值,因为如果无效,您只是丢弃newTime 并使用旧时间来代替Error 情况。

基于此,我建议改用以下模型:

type alias TimeInput =
    { seconds: Int
    , state: TimeInputState
    }

type TimeInputState = Error | Valid

type alias Model =
    { timeBetweenExercises : TimeInput
      ...
    }

并将您的更新功能更改为:

update : Msg -> Model -> Model
update msg model =
    case msg of
        TimeBetweenExercisesChanged newTime ->
            case String.toInt newTime of
                Nothing ->
                    { model
                        | timeBetweenExercises = 
                            { seconds = model.timeBetweenExercises.seconds
                            , state = Error
                            }
                    }

                Just time ->
                    { model
                        | timeBetweenExercises = 
                            { seconds = time
                            , state = Valid
                            }
                    }

否则,无论如何,您都可以只创建一个函数来提取Int

getSeconds : Seconds -> Int
getSeconds time =
    case time of
        Error seconds -> seconds
        Valid seconds -> seconds

【讨论】:

    猜你喜欢
    • 2018-04-06
    • 1970-01-01
    • 1970-01-01
    • 2021-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多