【发布时间】:2015-07-05 07:55:21
【问题描述】:
(有关上下文,请参阅this recent SO entry)。
我试图仅使用foldr 来定义zip:
zipp :: [a] -> [b] -> [(a,b)]
zipp xs ys = zip1 xs (zip2 ys)
where
-- zip1 :: [a] -> tq -> [(a,b)] -- zip1 xs :: tr ~ tq -> [(a,b)]
zip1 xs q = foldr (\ x r q -> q x r ) n xs q
-------- c --------
n q = []
-- zip2 :: [b] -> a -> tr -> [(a,b)] -- zip2 ys :: tq ~ a -> tr -> [(a,b)]
zip2 ys x r = foldr (\ y q x r -> (x,y) : r q ) m ys x r
---------- k --------------
m x r = []
{-
zipp [x1,x2,x3] [y1,y2,y3,y4]
= c x1 (c x2 (c xn n)) (k y1 (k y2 (k y3 (k y4 m))))
--------------- ----------------------
r q
= k y1 (k y2 (k y3 (k y4 m))) x1 (c x2 (c xn n))
---------------------- ---------------
q r
-}
它在纸上“有效”,但给出了两个“无限类型”错误:
Occurs check: cannot construct the infinite type:
t1 ~ (a -> t1 -> [(a, b)]) -> [(a, b)] -- tr
Occurs check: cannot construct the infinite type:
t0 ~ a -> (t0 -> [(a, b)]) -> [(a, b)] -- tq
显然,tr、tq 中的每个类型都以循环方式依赖于另一个。
有没有什么方法可以让它发挥作用,通过某种类型的巫术之类的?
我在 Win7 上使用 Haskell Platform 2014.2.0.0 和 GHCi 7.8.3。
【问题讨论】:
-
嗨 - 我在你原来的问题的答案中添加了默认技巧,向你展示如何修复你的
zip- 你应该能够使用它来让它工作(但是您将不得不对类型、定义等产生更多的困惑。) -
@CarstenKönig 不管;但我在这里不需要 mutually 递归类型吗?它与您在那里添加的内容有很大不同吗? (顺便说一句,我认为“编织”而不是压缩该 OP 的代码是他们的错误)
-
我并没有真正尝试过,使用 Either 来欺骗其中的不同类型可能更容易,使用奇怪的
zipCat,然后将其输出到unzip内联(如果你明白我的意思) -
@WillNess 这实际上是我想要的(相当于
(\a b -> concat (zipWith (\a b->[a,b]) a b))),因为我注意到如果没有元组构造函数它看起来会很好!不是真正尝试实现zip,而是获得洞察力。