Это функция zip учебника:
zip :: [a] -> [a] -> [(a,a)]
zip [] _ = []
zip _ [] = []
zip (x:xs) (y:ys) = (x,y) : zip xs ys
Ранее я спрашивал на #haskell, может ли «zip» быть реализован с использованием только «foldr», без рекурсии, без сопоставления с образцом. Немного подумав, мы заметили, что рекурсию можно устранить с помощью продолжений:
zip' :: [a] -> [a] -> [(a,a)]
zip' = foldr cons nil
where
cons h t (y:ys) = (h,y) : (t ys)
cons h t [] = []
nil = const []
У нас все еще остается сопоставление с образцом. После еще нескольких нейронных тостов я пришел к неполному ответу, который мне показался логичным:
zip :: [a] -> [a] -> [a]
zip a b = (zipper a) (zipper b) where
zipper = foldr (\ x xs cont -> x : cont xs) (const [])
Он возвращает плоский список, но выполняет застежку-молнию. Я был уверен, что это имеет смысл, но Haskell жаловался на тип. Я начал тестировать его на нетипизированном лямбда-калькуляторе, и он сработал. Почему Haskell не может принять мою функцию?
Ошибка:
zip.hs:17:19:
Occurs check: cannot construct the infinite type:
t0 ~ (t0 -> [a]) -> [a]
Expected type: a -> ((t0 -> [a]) -> [a]) -> (t0 -> [a]) -> [a]
Actual type: a
-> ((t0 -> [a]) -> [a]) -> (((t0 -> [a]) -> [a]) -> [a]) -> [a]
Relevant bindings include
b ∷ [a] (bound at zip.hs:17:7)
a ∷ [a] (bound at zip.hs:17:5)
zip ∷ [a] -> [a] -> [a] (bound at zip.hs:17:1)
In the first argument of ‘foldr’, namely ‘cons’
In the expression: ((foldr cons nil a) (foldr cons nil b))
zip.hs:17:38:
Occurs check: cannot construct the infinite type:
t0 ~ (t0 -> [a]) -> [a]
Expected type: a -> (t0 -> [a]) -> t0 -> [a]
Actual type: a -> (t0 -> [a]) -> ((t0 -> [a]) -> [a]) -> [a]
Relevant bindings include
b ∷ [a] (bound at zip.hs:17:7)
a ∷ [a] (bound at zip.hs:17:5)
zip ∷ [a] -> [a] -> [a] (bound at zip.hs:17:1)
In the first argument of ‘foldr’, namely ‘cons’
In the fourth argument of ‘foldr’, namely ‘(foldr cons nil b)’
(,)
как функцию, аhead
иtail
вместо (y:ys) и, возможно, if/else? - person Benjamin Gruenbaum   schedule 26.04.2015