Elm:自定义类型的访问值
Elm: Access value of custom type
我在 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
值?
在我看来模型是错误的,原因有二:
如果您有一个在所有情况下都通用的值,通常将其移出和移上一个级别会更方便。
您的更新函数表明 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
我在 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
值?
在我看来模型是错误的,原因有二:
如果您有一个在所有情况下都通用的值,通常将其移出和移上一个级别会更方便。
您的更新函数表明
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