Haskell 折叠解压
Haskell Unzip With Fold
我正在尝试弄清楚如何使用自定义版本的 fold(基本上用作 foldl)在 Haskell 中创建自定义解压缩函数,但我被卡住了。我可以拿到
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
谢谢
您的 lambda 函数有几个问题。
首先,fold
需要一个 (a -> b -> b)
,所以从技术上讲,一个有两个参数的函数。现在,您的 lambda 只接受 1 个参数。由于您的 fold
类似于 foldr
(从右边折叠),第二个参数应该是 accumulator 对象,它收集每次折叠的结果。
其次,您使用的是元组,而不是列表(如 )。因此,您应该使用 fst
和 snd
函数。
对 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")
继 之后,您还可以利用 lambda 中的模式匹配,取代 fst
和 snd
。这可能会增加函数的严格性。您还可以将 ([], [])
替换为 mempty
,一个预定义的空元组。
unzip' = fold (\(x, y) (xs, ys) -> (x:xs, y:ys)) mempty
提示:在进入 unzip
函数之前,您可以先用 fold
隔离并测试 lambda。
我正在尝试弄清楚如何使用自定义版本的 fold(基本上用作 foldl)在 Haskell 中创建自定义解压缩函数,但我被卡住了。我可以拿到
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
谢谢
您的 lambda 函数有几个问题。
首先,fold
需要一个 (a -> b -> b)
,所以从技术上讲,一个有两个参数的函数。现在,您的 lambda 只接受 1 个参数。由于您的 fold
类似于 foldr
(从右边折叠),第二个参数应该是 accumulator 对象,它收集每次折叠的结果。
其次,您使用的是元组,而不是列表(如 fst
和 snd
函数。
对 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")
继 fst
和 snd
。这可能会增加函数的严格性。您还可以将 ([], [])
替换为 mempty
,一个预定义的空元组。
unzip' = fold (\(x, y) (xs, ys) -> (x:xs, y:ys)) mempty
提示:在进入 unzip
函数之前,您可以先用 fold
隔离并测试 lambda。