prop_scaleData3 d n = n > 1 ==> length (scaleData d n) == n
prop_scaleData4 d n = n > 1 ==> head (scaleData d n) == -d
prop_scaleData5 d n = n > 1 ==> last (scaleData d n) == d
Просто посмотрите, что общего в этих трех функциях, и создайте новую вспомогательную функцию, которая извлекает общие черты. Например:
scaleProp :: Int -> Int -> ([Int] -> Int) -> Int -> Bool
scaleProp d n op res = n > 1 ==> op (scaleData d n) == res
Затем вы можете выразить свой исходный реквизит в терминах помощника:
prop_scaleData3 d n = scaleProp d n length n
prop_scaleData4 d n = scaleProp d n head (-d)
prop_scaleData4 d n = scapeProp d n last d
На этом этапе повторение касается не столько логики, сколько синтаксиса (именования функций и применения аргументов). В таких случаях я не думаю, что принцип DRY действительно полезен - вы можете делать меньше синтаксических повторений, но вы потеряете читаемость или модульность. Например, Toxaris объединил решения в одну функцию; мы можем сделать то же самое, но сделаем это проще, используя только списки логических значений:
prop_scaleData345 d n =
let sp = scaleProp d n
in and [sp length n, sp head (-d), sp last d]
-- or instead:
-- in all (uncurry sp) [(length, n), (head, negate d), (last, d)]
person
Thomas M. DuBuisson
schedule
12.04.2014