Elm:自定义类型的访问值

问题描述 投票:0回答:1

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

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值?

elm
1个回答
0
投票

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

  1. 如果您具有所有变体通用的值,通常更方便地将其上移或下移。因此,您可能会拥有:

  2. 您的更新功能表明Error状态实际上没有描述其持有的值,因为如果无效,您只是将newTime丢掉,而对于Error情况则使用旧时间。] >

  3. 基于此,我建议使用以下模型:

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: timeBetweenExercises.seconds
                            , state: Error
                            }
                    }

                Just time ->
                    { model
                        | timeBetweenExercises = 
                            { seconds: time
                            , state: Valid
                            }
                    }
``
© www.soinside.com 2019 - 2024. All rights reserved.