git.iko.soy/typeable/blog-posts-ru
on main help sign in
Updates
commit47544dc963c1c593665e0bf6abecd49858a81acc authorVladimir Kalnitsky <klntsky@typeable.io> dateMon 22 Feb 2021, 17:49 (6 years ago) parent09e56a4
2 files changed+29−28
elm-vs-reflex/elm-quiz-demo/src/Main.elm+11−9 elm-vs-reflex/reflex-quiz-demo/frontend/src/Frontend.hs+18−19
elm-vs-reflex/elm-quiz-demo/src/Main.elm+11−9
@@ -70,12 +70,8 @@ updateCanCheckAnswers model =
7070updateScore : Model -> Model
7171updateScore model =
7272 let
73− isCorrectAnswer (answer, isChosen) =
74− case (answer.isCorrect, isChosen) of
75− (Correct, Chosen) -> True
76− _ -> False
7773 hasCorrectAnswer (_, answers) =
78− List.any isCorrectAnswer answers
74+ List.any isCorrectAnswerChosen answers
7975 correctAnswers =
8076 List.length <| List.filter hasCorrectAnswer model.allQuestions
8177 totalQuestions = List.length model.allQuestions
@@ -84,10 +80,6 @@ updateScore model =
8480 Score { correctAnswers = correctAnswers
8581 , totalQuestions = totalQuestions } }
8682
87−hasChosenAnswer : (QuestionText, List (Answer, IsChosen)) -> Bool
88−hasChosenAnswer (_, answers) =
89− List.any (\(_, isChosen) -> isChosen == Chosen) answers
90−
9183updateAnswers : Int -> IsChosen -> List (Answer, IsChosen) -> List (Answer, IsChosen)
9284updateAnswers answerIx newIsChosen =
9385 List.indexedMap <| \aix ->
@@ -158,6 +150,16 @@ toggleChosen isChosen =
158150 Chosen -> NotChosen
159151 NotChosen -> Chosen
160152
153+hasChosenAnswer : (QuestionText, List (Answer, IsChosen)) -> Bool
154+hasChosenAnswer (_, answers) =
155+ List.any (\(_, isChosen) -> isChosen == Chosen) answers
156+
157+isCorrectAnswerChosen : (Answer, IsChosen) -> Bool
158+isCorrectAnswerChosen (answer, isChosen) =
159+ case (answer.isCorrect, isChosen) of
160+ (Correct, Chosen) -> True
161+ _ -> False
162+
161163mapAllQuestions : (Questions -> Questions) -> Model -> Model
162164mapAllQuestions f model = { model | allQuestions = f model.allQuestions }
163165
elm-vs-reflex/reflex-quiz-demo/frontend/src/Frontend.hs+18−19
@@ -58,28 +58,27 @@ data CheckAnswers = CheckAnswers
5858-- ** Типы данных, описывающие внутренние интерфейсы нашего виджета.
5959
6060-- | Тип, содержащий все события, с которыми мы будем работать.
61−data Events t = Events
61+data QuizEvents t = QuizEvents
6262 { selectAnswer :: Event t SelectAnswer
6363 , showAnswers :: Event t CheckAnswers }
6464
6565-- | Тип, содержащий все изменяющиеся (Dynamic) данные.
66−data Model t
67− = Model
68− { areAnswersShown :: Dynamic t AreAnswersShown
69− , allQuestions :: [(QuestionText, [(Answer, Dynamic t IsChosen)])]
70− , canCheckAnswers :: Dynamic t CanCheckAnswers
71− , score :: Dynamic t Score }
66+data QuizState t = QuizState
67+ { areAnswersShown :: Dynamic t AreAnswersShown
68+ , allQuestions :: [(QuestionText, [(Answer, Dynamic t IsChosen)])]
69+ , canCheckAnswers :: Dynamic t CanCheckAnswers
70+ , score :: Dynamic t Score }
7271
7372-- * Model
7473
7574-- | Функция, описывающая всю внутреннюю логику работы виджета. Она принимает
76−-- тип данных 'Events', хранящий все события и возвращает динамическую модель.
77−mkModel :: ObeliskWidget js t route m
75+-- тип данных 'QuizEvents', хранящий все события и возвращает динамическую модель.
76+mkQuizModel :: ObeliskWidget js t route m
7877 => [(QuestionText, [Answer])]
7978 -- ^ Список вопросов с ответами
80− -> Events t
81− -> m (Model t)
82−mkModel questions evs = do
79+ -> QuizEvents t
80+ -> m (QuizState t)
81+mkQuizModel questions evs = do
8382 areAnswersShown <- holdDyn AnswersHidden $ showAnswers evs $> AnswersShown
8483 allQuestions <- do
8584 for (enumerate questions) \(qNum, (questionText, answers)) -> do
@@ -111,19 +110,19 @@ mkModel questions evs = do
111110 when (isChosen == Chosen && isCorrect answer == Correct) do
112111 modify (+ 1)
113112 return Score {correctAnswers, totalQuestions = length allQuestions}
114− return Model{..}
113+ return QuizState{..}
115114
116115-- * Интерфейс пользователя
117116
118−quizUI :: ObeliskWidget js t route m => Model t -> m (Events t)
119−quizUI Model{..} = wrapUI do
117+quizUI :: ObeliskWidget js t route m => QuizState t -> m (QuizEvents t)
118+quizUI QuizState{..} = wrapUI do
120119 selectAnswer <- leftmost <$> for (enumerate allQuestions)
121120 \(qNum, (questionText, answers)) -> do
122121 divClass "question" do
123122 text questionText
124123 answersUI qNum areAnswersShown answers
125124 showAnswers <- footerUI canCheckAnswers score
126− return Events{..}
125+ return QuizEvents{..}
127126
128127answersUI :: ObeliskWidget js t route m
129128 => Int
@@ -221,13 +220,13 @@ questions =
221220
222221mkQuizWidget :: ObeliskWidget js t route m => [(QuestionText, [Answer])] -> m ()
223222mkQuizWidget qs =
224− mkWidget (mkModel qs) quizUI
223+ mkWidget (mkQuizModel qs) quizUI
225224
226225-- * Вспомогательные функции.
227226
228227mkWidget :: ObeliskWidget js t route m
229− => (events -> m model) -> (model -> m events) -> m ()
230−mkWidget model ui = void $ mfix (model >=> ui)
228+ => (events -> m state) -> (state -> m events) -> m ()
229+mkWidget model ui = void (mfix (model >=> ui))
231230
232231enumerate :: [a] -> [(Int, a)]
233232enumerate = zip [0..]