如何改进这些haskell压缩和解压缩功能?
指定通过将相同的连续元素转换为逐个元素对来压缩列表的函数。群组功能很有用。
指定从压缩列表恢复原始的功能。复制功能可能很有用。
import Data.List
compress :: (Eq a, Integral b) => [a] -> [(b, a)]
compress l = zip (length $ group l) (head $ group l)
Or:
compress :: (Eq a, Integral b) => [a] -> [(b, a)]
compress [] = []
compress (x:xs)
| x == a = (b+1,a) : xs
| otherwise = (1,a) : compress (b,a) xs
decompress :: (Eq a, Integral b) => [(b, a)] -> [a]
decompress l = concat [replicate (fst x) (snd x) | x <- l]
Examples:
compress "aaaabccaadeeee" == [(4, 'a'), (1, 'b'), (2, 'c'), (2, 'a'), (1, 'd'), (4, 'e')]
compress "oh hello !!" == [(1, 'o'), (1, 'h'), (1, ''), (1, 'h'), (1, 'e'), (2, 'l'), (1, 'o'), (2, '!')]
compress [] == []
compress [1,1,0,0,0,1,1,1] == [(2.1), (3.0), (3.1)]
decompress [(4, 'a'), (1, 'b'), (2, 'c'), (2, 'a'), (1, 'd'), (4, 'e')] == "aaaabccaadeeee"
decompress [(1, 'o'), (1, 'h'), (1, ''), (1, 'h'), (1, 'e'), (2, 'l'), ( 1, 'o'), (2, '!')] == "oh hello !!"
decompress [] == []
decompress [(2,1), (3,0), (3,1)] == [1,1,0,0,0,1,1,1]
Specify the function that compresses a list by converting identical consecutive elements into number-by-element pairs. The group function can be useful.
Specify the function that restores the original from a compressed list. The replicate function can be useful.
import Data.List
compress :: (Eq a, Integral b) => [a] -> [(b, a)]
compress l = zip (length $ group l) (head $ group l)
Or:
compress :: (Eq a, Integral b) => [a] -> [(b, a)]
compress [] = []
compress (x:xs)
| x == a = (b+1,a) : xs
| otherwise = (1,a) : compress (b,a) xs
decompress :: (Eq a, Integral b) => [(b, a)] -> [a]
decompress l = concat [replicate (fst x) (snd x) | x <- l]
Examples:
compress "aaaabccaadeeee" == [(4, 'a'), (1, 'b'), (2, 'c'), (2, 'a'), (1, 'd'), (4, 'e')]
compress "oh hello !!" == [(1, 'o'), (1, 'h'), (1, ''), (1, 'h'), (1, 'e'), (2, 'l'), (1, 'o'), (2, '!')]
compress [] == []
compress [1,1,0,0,0,1,1,1] == [(2.1), (3.0), (3.1)]
decompress [(4, 'a'), (1, 'b'), (2, 'c'), (2, 'a'), (1, 'd'), (4, 'e')] == "aaaabccaadeeee"
decompress [(1, 'o'), (1, 'h'), (1, ''), (1, 'h'), (1, 'e'), (2, 'l'), ( 1, 'o'), (2, '!')] == "oh hello !!"
decompress [] == []
decompress [(2,1), (3,0), (3,1)] == [1,1,0,0,0,1,1,1]
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您在这里枚举了两次
group
的结果。您可以简化这一点并使用映射函数将组结果的每个项目转换为 2 元组,例如使用(&&&) :: 箭头 a => abc-> ab c'-> ab (c, c')
.length :: 可折叠f =>发-> Int
返回一个Int
,因此您不能使用任何Integral
类型:为了解压缩,我们可以使用
concatMap :: 可折叠 t => (a→[b])→塔-> [b]
并使用uncurry :: (a -> b -> c) -> (a、b)→ c
创建一个适用于 2 元组的replicate
变体。replicate :: Int ->一个-> [a]
适用于Int
,而不是任何Integral
和Eq
类型约束这里不需要,因为我们可以复制任何项目。concatMap
可以在任何Foldable
上工作,因此我们可以将类型签名概括为:You are here enumerating over the result of a
group
twice. You can simplify this and work with a mapping function that transforms each item of the result of group to a 2-tuple, for example with(&&&) :: Arrow a => a b c -> a b c' -> a b (c, c')
.length :: Foldable f => f a -> Int
returns anInt
, so you can not use anyIntegral
type:For decompressing, we can make use of
concatMap :: Foldable t => (a -> [b]) -> t a -> [b]
and useuncurry :: (a -> b -> c) -> (a, b) -> c
to create a variant ofreplicate
that works on a 2-tuple instead.replicate :: Int -> a -> [a]
works on anInt
, not anyIntegral
, and theEq
type constraint is not necessary here, since we can replicate any item.concatMap
can work on anyFoldable
, so we can generalize the type signature to: