Haskell解压缩

问题描述 投票:1回答:1

我正在试图弄清楚如何使用自定义版本的折叠在Haskell中创建自定义解压缩函数(基本上用作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

谢谢

haskell unzip fold
1个回答
4
投票

lambda函数有几个问题。

首先,fold期望一个(a -> b -> b),从技术上讲,它是一个有两个参数的函数。现在,你的lambda只接受1个参数。由于你的fold类似于foldr(从右边折叠),第二个参数应该是累加器对象,它从每个折叠收集结果。

其次,你正在使用元组,而不是列表(如pdexter noted in a comment)。因此,您应该使用fstsnd函数。

经过对lambda的一些修改:

\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")

Jon's comment之后,您还可以利用lambda中的模式匹配,替换fstsnd。这可能会增加功能的严格性。你也可以用([], [])替换memptyunzip' = fold (\(x, y) (xs, ys) -> (x:xs, y:ys)) mempty 是一个预定义的空元组。

unzip

提示:在跳入fold函数之前,您可以先用qazxswpoi隔离并测试lambda。

© www.soinside.com 2019 - 2024. All rights reserved.