Объединить 2 функции списка в 1? - PullRequest
0 голосов
/ 04 мая 2011

Как бы я соединил следующие две функции:

replaceNth n newVal (x:xs)
 | n == 0 = newVal:xs
 | otherwise = x:replaceNth (n-1) newVal xs

replaceMthNth m n v arg = replaceNth m (replaceNth n v (arg !! m)) arg

в одну функцию?

Возможно ли это?

Ответы [ 5 ]

3 голосов
/ 04 мая 2011

Это довольно отвратительно, но делает свою работу:

replacemn 0 0 z ((x : xs) : xss) = (z : xs) : xss
replacemn 0 n z ((x : xs) : xss) =
  let (ys : yss) = replacemn 0 (n-1) z (xs : xss)
  in ((x : ys) : yss)
replacemn m n z (xs:xss) = xs : replacemn (m-1) n z xss
2 голосов
/ 04 мая 2011

Хорошо, здесь речь идет об отсутствии других именованных функций в глобальном пространстве имен, использовании каких-либо предложений where или let или любых других глобальных функций.

{-# LANGUAGE ScopedTypeVariables,RankNTypes #-}
module Temp where
newtype Mu a = Mu (Mu a -> a)

replaceMthNth :: Int -> Int -> a -> [[a]] -> [[a]]
replaceMthNth = (\h (f :: Int -> forall b . b -> [b] -> [b]) -> h f f)
                  ( \replaceNth replaceNth' ->
                    -- definition of replaceMthNth in terms of some replaceNth and replaceNth'
                    \m n v arg -> replaceNth m (replaceNth' n v (arg !! m)) arg
                  )
                  $
                    -- y combinator
                    ((\f -> (\h -> h $ Mu h) $ \x -> f $ (\(Mu g) -> g) x $ x) :: (a -> a) -> a) $
                    (\replaceNth ->
                      -- definition of replaceNth given a recursive definition 
                      (\(n::Int) newVal xs -> case xs of
                          [] -> []
                          (x:xs) -> if n == 0 then newVal:xs else x:replaceNth (n-1) newVal xs
                      )
                    )
2 голосов
/ 04 мая 2011

Состав функции

Функции в Haskell могут быть составлены бесплатно. Например. учитывая две функции, f и g, вы можете объединить их в новую функцию: f . g, которая применяет g к аргументу, затем применяет f к результату. Вы должны быть в состоянии использовать композицию таким же образом здесь.

1 голос
/ 04 мая 2011

Я вообще не понимаю, что это за вопрос :), но вот как я бы это реализовал:

modifyNth :: Int -> (a -> a) -> [a] -> [a]
modifyNth n f (x:xs)
  | n == 0 = f x : xs
  | otherwise = x : modifyNth (n-1) f xs

replaceNthMth :: Int -> Int -> a -> [[a]] -> [[a]]
replaceNthMth m n v = modifyNth m (modifyNth n (const v))

Таким образом, вам не нужно дважды просматривать список (в первый разс !!, второй раз с replaceNth)

0 голосов
/ 04 мая 2011

Вот гротескная реализация, которая перестраивает 2-мерную структуру списков с вложенными списками на основе почтовых индексов с бесконечными списками:

replaceMthNth :: Int -> Int -> a -> [[a]] -> [[a]]
replaceMthNth m n v ass = [[if (x,y) == (m,n) then v else a
                            | (y, a) <- zip [0..] as]
                           | (x, as) <- zip [0..] ass]
...