Haskell Unzip With Fold - PullRequest
       29

Haskell Unzip With Fold

0 голосов
/ 02 марта 2019

Я пытаюсь выяснить, как создать пользовательскую функцию распаковки в Haskell, используя пользовательскую версию fold (в основном работает как foldl), но я застрял.Я могу получить его на

unzip' :: [(a,b)] -> ([a],[b])
unzip' = fold (\x->([x!!0],[x!!1])) ([],[])

Но с ошибками:

• Couldn't match expected type ‘[a]’
              with actual type ‘(Integer, Integer)’
• In the first argument of ‘tail’, namely ‘(1, 2)’
  In the expression: tail (1, 2)
  In an equation for ‘it’: it = tail (1, 2)
• Relevant bindings include
    it :: [a] (bound at <interactive>:114:1)

Из того, что я считаю, x - это (1,2), но я не уверен, как дальшеразделите его на 1 и 2. Вот функция сгиба, которую я использую:

fold :: (a -> b -> b) -> b -> ([a] -> b)
fold c n =
  let f [] = n
      f (x:xs) = x `c` (f xs)
  in f

Спасибо

1 Ответ

0 голосов
/ 02 марта 2019

Есть несколько проблем с вашей лямбда-функцией.

Во-первых, fold ожидает (a -> b -> b), то есть технически, функцию с двумя аргументами.Прямо сейчас ваша лямбда принимает только 1 аргумент.Поскольку ваш fold напоминает foldr (сгиб справа), вторым аргументом должен быть объект аккумулятор , который собирает результат с каждого сгиба.

Во-вторых, вы работаетес кортежами, а не списками (как отмечено в комментарии pdexter ).Таким образом, вы должны использовать функции fst и snd.

После некоторых модификаций лямбды:

\x acc -> (fst x:fst acc, snd x:snd acc)

Это добавит первый элемент из каждого кортежа в первый списокаккумулятора.И второй элемент из каждого кортежа во второй список аккумулятора.Некоторые результаты:

unzip' :: [(a,b)] -> ([a],[b])
unzip' = fold (\x acc -> (fst x:fst acc, snd x:snd acc)) ([],[])

unzip' [(1, 'a'), (2, 'b'), (3, 'c')]
([1,2,3],"abc")

После комментария Джона вы также можете воспользоваться преимуществами сопоставления с образцом в лямбда-выражении, заменив fst и snd.Это может увеличить строгость функции.Вы также можете заменить ([], []) на mempty, предопределенный пустой кортеж.

unzip' = fold (\(x, y) (xs, ys) -> (x:xs, y:ys)) mempty

Совет: Перед тем, как перейти к функции unzip, вы можете изолировать и проверить лямбду с помощьюfold первый.

...