Особенности реализации
This commit is contained in:
@@ -183,6 +183,100 @@
|
||||
|
||||
\newpage
|
||||
\section {Особенности реализации}
|
||||
\subsection{Функция isCongruent}
|
||||
|
||||
Код функции для проверки числовой конгруэнтности представлен в листинге~\ref{lst:is-congruent}. Функция \texttt{isCongruent} принимает три числа: \texttt{a}, \texttt{b} и \texttt{d}. Она возвращает \texttt{True}, если остатки от деления \texttt{a} и \texttt{b} на \texttt{d} равны, и \texttt{False} в противном случае.
|
||||
|
||||
\begin{lstlisting}[caption={Функция для проверки числовой конгруэнтности.}, label={lst:is-congruent}]
|
||||
isCongruent :: Int -> Int -> Int -> Bool
|
||||
isCongruent a b d = a `mod` d == b `mod` d
|
||||
\end{lstlisting}
|
||||
|
||||
\subsection{Функция filterByPredicate}
|
||||
|
||||
Код функции для фильтрации элементов списка на основе предиката представлен в листинге~\ref{lst:filter-by-predicate}. Функция \texttt{filterByPredicate} принимает предикат (\texttt{predicate}) и список (\texttt{[a]}). Она возвращает новый список, содержащий только те элементы исходного списка, для которых предикат возвращает \texttt{True}.
|
||||
|
||||
\begin{lstlisting}[caption={Функция для фильтрации списка по предикату.}, label={lst:filter-by-predicate}]
|
||||
filterByPredicate :: (a -> Bool) -> [a] -> [a]
|
||||
filterByPredicate _ [] = []
|
||||
filterByPredicate predicate (x:xs)
|
||||
| predicate x = x : filteredTail
|
||||
| otherwise = filteredTail
|
||||
where
|
||||
filteredTail = filterByPredicate predicate xs
|
||||
\end{lstlisting}
|
||||
|
||||
|
||||
\subsection{Тесты для функции isCongruent}
|
||||
|
||||
Для тестирования функции \texttt{isCongruent} использовались свойства, проверяемые с использованием библиотеки QuickCheck. Ниже приведены описания тестов, представленных в листинге~\ref{lst:congruent-tests}.
|
||||
|
||||
\begin{itemize}
|
||||
\item \texttt{propCongruentDifference}: Проверяет, что два числа конгруэнтны по модулю \texttt{m}, если и только если разность этих чисел делится на \texttt{m} без остатка.
|
||||
\item \texttt{propCongruentSymmetric}: Проверяет симметричность конгруэнтности, то есть, если \texttt{a} конгруэнтно \texttt{b}, то \texttt{b} конгруэнтно \texttt{a}.
|
||||
\item \texttt{propCongruentEqualNumbers}: Проверяет, что любое число \texttt{a} всегда конгруэнтно самому себе по любому ненулевому модулю.
|
||||
\end{itemize}
|
||||
|
||||
\begin{lstlisting}[caption={Тесты для функции \texttt{isCongruent} с использованием QuickCheck.}, label={lst:congruent-tests}]
|
||||
propCongruentDifference :: Int -> Int -> Int -> Property
|
||||
propCongruentDifference a b m =
|
||||
m /= 0 ==> isCongruent a b m == ((a - b) `mod` m == 0)
|
||||
|
||||
propCongruentSymmetric :: Int -> Int -> Int -> Property
|
||||
propCongruentSymmetric a b m =
|
||||
m /= 0 ==> isCongruent a b m == isCongruent b a m
|
||||
|
||||
propCongruentEqualNumbers :: Int -> Int -> Property
|
||||
propCongruentEqualNumbers a m =
|
||||
m /= 0 ==> isCongruent a a m == True
|
||||
\end{lstlisting}
|
||||
|
||||
|
||||
\subsection{Тесты для функции filterByPredicate}
|
||||
|
||||
Для тестирования функции \texttt{filterByPredicate} использовались свойства, проверяемые с использованием библиотеки QuickCheck. Описание тестов приведено в листинге~\ref{lst:filter-tests}.
|
||||
|
||||
\begin{itemize}
|
||||
\item \texttt{propFilterByPredicateSatisfiesPredicate}: Проверяет, что все элементы результирующего списка удовлетворяют переданному предикату.
|
||||
\item \texttt{propFilterByPredicateLength}: Проверяет, что длина результирующего списка не превышает длину исходного списка.
|
||||
\item \texttt{propFilterByPredicateAlwaysTrue}: Проверяет, что если предикат всегда возвращает \texttt{True}, результирующий список совпадает с исходным.
|
||||
\end{itemize}
|
||||
|
||||
\begin{lstlisting}[caption={Тесты для функции \texttt{filterByPredicate} с использованием QuickCheck.}, label={lst:filter-tests}]
|
||||
propFilterByPredicateSatisfiesPredicate :: Fun Int Bool -> [Int] -> Bool
|
||||
propFilterByPredicateSatisfiesPredicate (Fun _ predicate) xs =
|
||||
all predicate (filterByPredicate predicate xs)
|
||||
|
||||
propFilterByPredicateLength :: Fun Int Bool -> [Int] -> Bool
|
||||
propFilterByPredicateLength (Fun _ predicate) xs =
|
||||
length (filterByPredicate predicate xs) <= length xs
|
||||
|
||||
propFilterByPredicateAlwaysTrue :: [Int] -> Bool
|
||||
propFilterByPredicateAlwaysTrue xs =
|
||||
filterByPredicate (\_ -> True) xs == xs
|
||||
\end{lstlisting}
|
||||
|
||||
|
||||
\subsection{Запуск тестов}
|
||||
|
||||
Для выполнения всех тестов в проекте создан файл \texttt{Spec.hs}, в котором определена функция \texttt{main}. Она последовательно запускает все тесты, используя библиотеку \texttt{QuickCheck}. Код функции \texttt{main} приведён в листинге~\ref{lst:test-main}.
|
||||
|
||||
Функция \texttt{quickCheck} используется для автоматического тестирования свойств. Она генерирует случайные входные данные, проверяет выполнение свойства на каждом из них и сообщает о результатах. В случае провала теста \texttt{quickCheck} предоставляет пример данных, на которых свойство не выполняется.
|
||||
|
||||
Для сборки проекта и выполнения всех тестов достаточно выполнить команду \texttt{stack test}.
|
||||
|
||||
\begin{lstlisting}[caption={Функция \texttt{main} для запуска тестов.}, label={lst:test-main}]
|
||||
main :: IO ()
|
||||
main = do
|
||||
quickCheck propCongruentDifference
|
||||
quickCheck propCongruentSymmetric
|
||||
quickCheck propCongruentEqualNumbers
|
||||
|
||||
quickCheck propFilterByPredicateSatisfiesPredicate
|
||||
quickCheck propFilterByPredicateLength
|
||||
quickCheck propFilterByPredicateAlwaysTrue
|
||||
\end{lstlisting}
|
||||
|
||||
|
||||
|
||||
\newpage
|
||||
|
||||
Reference in New Issue
Block a user