所以我有一个数据列表,我知道newtype目前更好,但我会添加更多的东西。我想将Pack列表转换为String。
unpack [Pack ('a','b'), Pack ('c','d') , Pack (' ', 'e') ] = "abcd e"
我正在考虑使用折叠,但我试图搞清楚。
data Pack= Pack (Char, Char) deriving ( Show)
unPack:: [Pack] -> String
unpack list = foldr (\Pack (a,b) -> show a + show b -> concat) "" list
谢谢你的帮助
你的Pack
类型与两个字符的字符串是同构的:
pack2String :: Pack -> String
pack2String (Pack (a,b)) = a:[b]
string2Pack :: String -> Pack -- partial, since String isn't limited in length
string2Pack (a:[b]) = Pack (a, b)
(请注意,Pack (a,b)
已经添加了不必要的包装级别; data Pack = Pack Char Char
也与Pack (Char, Char)
同构。)
因此,你实际上并不需要foldr
;你可以使用列表monad代替。
unpack :: [Pack] -> String
unpack xs = xs >>= pack2String
如果你还不熟悉monad,你可以直接使用concatMap
函数:
unpack :: [Pack] -> String
unpack = concatMap pack2String
要在lambda中对Pack xyz
进行模式修补,您需要将其放在括号中:
foldr (\(Pack (a,b)) -> ...)
你写的内容实际上会解析成两个独立的参数
foldr (\(Pack) -> \(a,b) -> ...)
接下来,你不能用+
连接字符串,这是数字。 ++
或<>
用于列表/字符串。
然后,-> concat
不是有效的语法。你想要做的是将foldr计算的其余部分连接到显示的a
和b
。剩余部分是折叠函数的第二个参数:
foldr (\(Pack (a,b)) rest -> show a ++ show b ++ rest)
......或更短,
foldr (\(Pack (a,b)) -> shows a . shows b)