Haskell - Как объявить функцию Positions с помощью Find? - PullRequest
0 голосов
/ 20 сентября 2018

Я очень новичок в изучении программирования на Haskell.

У меня есть пример метода positions:

positions :: Eq a => a -> [a] -> [Int]
positions x xs = [i | (y, i) <- zip xs [0..], y == x]

Моя цель - найти способопределить функцию positions, но с помощью метода find.

Метод find:

find :: Eq a => a -> [(a,b)] -> [b]
find k t = [v | (m, v) <- t, m == k]

Может кто-нибудь объяснить, как вы объявляете функцию positions с помощью только функция find?

Я не понимаю, как можно отслеживать индекс с помощью функции find.

Ответы [ 2 ]

0 голосов
/ 20 сентября 2018

Смотри:

positions x xs = [i | (y, i) <- zip xs [0..], y == x]
find      k t  = [v | (m, v) <- t           , m == k]

Они выглядят очень похоже!Мы можем сделать его еще более поразительным, просто переименовав k в x, m в y и v в i в реализации find:

positions x xs = [i | (y, i) <- zip xs [0..], y == x]
find      x t  = [i | (y, i) <- t           , y == x]

Теперь ясно: все, что нам нужно сделать, это positions передать zip xs [0..] в качестве аргумента t для find.

positions x xs = find x (zip xs [0..])
0 голосов
/ 20 сентября 2018

Мы начинаем с переписывания positions как

positions x xs = map (\(_, i) -> i) . filter (\(y, _) -> y == x) $ zip xs [0..]

и переписываем find как

find k t       = map (\(_, v) -> v) . filter (\(m, _) -> m == k) $ t
-- or,
find x         = map (\(_, i) -> i) . filter (\(y, _) -> y == x) 

, а затем просто замечаем, что две части кода точно одинаковы (после переименования переменных):

positions x xs = find x                                          $ zip xs [0..]

find принимает только списки пар , затем фильтрует их и извлекает второй компонент;вам придется использовать что-то (например, zip), чтобы получить пары для обработки find. нет пути вокруг него.


Конечно, positions также можно кодировать без части zip (вместо этого, например, используя mapAccumL), но тогда это не такнужно find:

-- mapAccumL :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])

positions :: (Eq a) => a -> [a] -> [Int]
positions x = concat . snd . mapAccumL g 0 
  where
  g acc y = (acc+1, [acc | y == x])

Мы могли бы сделать так, чтобы список получился, как и ожидалось, к find, искусственно, но это потребует много работы и просто будет повторной реализациейzip с перечислительной частью (то есть, не самой find), в любом случае.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...