Шаг 78.
Основы языка Haskell.
Функции обработки списков. Демонстрационные примеры

    На этом шаге мы рассмотрим несколько демонстрационных примеров.

    Приведем несколько демонстрационных примеров.

   -- Демонстрация полиморфной функции, "возвращающей"
   -- список из аргумента
   ----------------------
   lstEl:: a -> [a]
   lstEl x = [x]
   ----------------------------------------------------
   -- Функция, возвращающая заданный список без первого
   -- и последнего элемента и в перевёрнутом виде:
   --  (1) с использованием привычной математической
   -- формы композиции;
   --  (2) с использованием операции композиции (.);
   --  (3) с использованием бесточечной формы записи 
   -------------------------------------------------
   body:: [Char] -> [Char]
   body lst = reverse (tail (init lst))
   ------------------------------------
   body1:: [Char] -> [Char]
   body1 = reverse.tail.init
   --------------------------
   body2:: (->) [Char] [Char]
   body2 = (.) ((.) reverse tail) init
   -----------------------------------
   -- Неудачные тестовые примеры:
   --------------------------------
   test1 =   lstEl 1         == [1]
          && lstEl 'a'       == ['a']
          && lstEl "abc def" == ["abc def"]
          && lstEl True      == [True]
   --------------------------------------
   test2 =   body ['a','n']         == []
          && body ['f','a','b','a'] == ['b','a'] 
          && body ['f','a','b','a'] == "ba" 
          && body "q1234567b"       == "7654321" 
   ---------------------------------------------
   test3 =   body1 ['a','n']         == []
          && body1 ['f','a','b','a'] == ['b','a'] 
          && body1 ['f','a','b','a'] == "ba" 
          && body1 "q1234567b"       == "7654321" 
   ----------------------------------------------
   test4 =   body2 ['a','n']         == []
          && body2 ['f','a','b','a'] == ['b','a'] 
          && body2 ['f','a','b','a'] == "ba" 
          && body2 "q1234567b"       == "7654321"
   ----------------------------------------------
   test5 = f "q1234567b" "q1234567b"
            where f = (.) (flip ((.) (==) body1)) body2
Файл с примерами можно взять здесь.
   -- Демонстрация проверки тождеств, связанных с
   -- функциями: 
   --   head, tail; init, last; take, drop
   -------------------------------------------------
   test lst@(x:xs) =   x:xs                   == lst
                    && head lst:xs            == lst
                    && x:tail lst             == lst
                    && head lst:tail lst      == lst
                    && take 1 lst++drop 1 lst == lst
                    --------------------------------
                    && init lst++[last lst]   == lst
                    && take (len-1) lst++
                       drop (len-1) lst       == lst
                    ---------------------------------------
                    && head lst:(init.tail) lst++[last lst] 
                                              == lst
                    --------------------------------------
                    && s((.)(++)(take len)) (drop len) lst
                                              == lst
        where len     = length lst
              s x y z = x z (y z)
Файл с примерами можно взять здесь.
   -- Укажите прагматику приведённых ниже функций
   ----------------------------------------------
   cdr lst | null lst = lst
           | True     = tail lst
   -----------------------------
   doub lst | null lst = lst
            | True     = head lst : lst
   ---------------------------------------------------
   posl lst | null lst = error "Недопустимый аргумент" 
            | True     = (head.reverse) lst
   ----------------------------------------
   inlist:: Eq a => [a] -> Bool
   inlist lst = (.) (flip ((.) elem head)) tail lst lst 
   ----------------------------------------------------
   swap:: (->) [a] [a]
   swap lst = reverse 
                 (head lst: 
                    reverse (head (reverse lst):
                             reverse (tail (reverse (tail lst))))
                 )
   ----------------------
   predct:: [Int] -> Bool
   predct lst | null lst                      = False
              | sum lst `mod` (length lst)==0 = True
              | True                          = False
   --------------------------------------------------
   prodsum:: [Int] -> Int
   prodsum lst = product lst - sum lst
   -----------------------------------
   sqList:: (->) [Int] Bool
   sqList lst | null lst                       = undefined
              | product lst==fact (length lst) = True
              | True                           = False
     where fact n | n==0 = 1
                  | True = n*fact (n-1)
   ------------------------------------  
   abc:: (->) [Int] ((->) [Int] [Int])
   abc lst1 lst2 | sum lst1==sum lst2 && lst1==lst2 = lst1
                 | True                             = lst2
   -------------------------------------------------------
   -- Неудачные тестовые примеры:
   ------------------------------
   test1 =   predct [1,2,3]
          && predct [1,2,3,4,5] 
          && not (predct [1,7,3,4])
          && not (predct []) 
   ------------------------------------
   test2 =   prodsum [1,2,3]     ==   0
          && prodsum [1,2,3,4,5] == 105 
   -----------------------------------------------
   test3 =   swap [1,2,5,8]           == [8,2,5,1]
          && swap [1,7,8,9,89]        == [89,7,8,9,1]
          && swap [1,89,0,8,7,9,80]   == [80,89,0,8,7,9,1]
          && swap [9,8,7,6,5,4,2,3,1] == [1,8,7,6,5,4,2,3,9]
          && swap [1,5,6]             == [6,5,1]
          && swap [1,5]               == [5,1]
          && swap [9,0,8,6,7,5]       == [5,0,8,6,7,9]
          && swap [1,2,3,4,5,6,7,8,9] == [9,2,3,4,5,6,7,8,1]
   ---------------------------------------------------------
   test4 =   not (sqList [1,2,3,4,6,7,8])
          && not (sqList [3,4,6,7,8])
          && not (sqList [4,6,7,8])
          && not (sqList [11,6,7,8])
          && sqList [1,2,3,4]
   ----------------------------------------------
   test5 =   abc [9,8,5,7] [4,6,6,7] == [4,6,6,7]
          && abc [1,2,3] [7,8,9]     == [7,8,9]
          && abc [2,3,1] [2,3,1]     == [2,3,1]
   --------------------------------------------
   test6 =   not (inlist [1,2,3,4])
          && inlist [1,2,1,4]
          && inlist [1,1,1,1]
Файл с примерами можно взять здесь.
   -- Функция, перемещающая первые 1<=k<n элементов списка, 
   -- содержащего n элементов, в конец списка, не нарушая
   -- исходного порядка следования элементов.
   --   Воспользуемся эквивалентной функцией в языке muLISP
   --
   -- (DEFUN ABC (LAMBDA (LST k)
   --    (REVERSE (APPEND 
   --                (REVERSE (FIRSTN (MOD k (LENGTH LST)) LST)) 
   --                (REVERSE (NTHCDR (MOD k (LENGTH LST)) LST))
   --             )
   --    )
   -- ))
   ---------------------------
   abc:: [Int] -> Int -> [Int]
   abc lst k = reverse (
                        (reverse (take rest lst)) ++ 
                        (reverse (drop rest lst))
                       ) 
        where rest = k `mod` length lst
   ------------------------------------
   -- Простое решение:
   ----------------------------
   abc1:: [Int] -> Int -> [Int]
   abc1 lst k = drop k lst ++ take k lst
   -------------------------------------
   -- Неудачные тестовые примеры:
   -----------------------------------------------
   test1 =   abc [1,2,3,4,5,6]  0 == [1,2,3,4,5,6]
          && abc [1,2,3,4,5,6]  1 == [2,3,4,5,6,1]
          && abc [1,2,3,4,5,6]  2 == [3,4,5,6,1,2]
          && abc [1,2,3,4,5,6]  3 == [4,5,6,1,2,3]
          && abc [1,2,3,4,5,6]  5 == [6,1,2,3,4,5]
          && abc [1,2,3,4,5,6]  6 == [1,2,3,4,5,6]
          && abc [1,2,3,4,5,6] 36 == [1,2,3,4,5,6]
          && abc [1,2,3,4,5,6] 38 == [3,4,5,6,1,2]
          && abc [1,2,3,4,5,6] 41 == [6,1,2,3,4,5]
   ------------------------------------------------
   test2 =   abc1 [1,2,3,4,5,6] 0  == [1,2,3,4,5,6]
          && abc1 [1,2,3,4,5,6] 1  == [2,3,4,5,6,1]
          && abc1 [1,2,3,4,5,6] 2  == [3,4,5,6,1,2]
          && abc1 [1,2,3,4,5,6] 3  == [4,5,6,1,2,3]
          && abc1 [1,2,3,4,5,6] 5  == [6,1,2,3,4,5]
          && abc1 [1,2,3,4,5,6] 6  == [1,2,3,4,5,6]
Файл с примерами можно взять здесь.

    На следующем шаге мы рассмотрим понятие "кортеж" .




Предыдущий шаг Содержание Следующий шаг