问题描述
我想重写(或升级!:))我的两个函数,hist
和 sort
,使用折叠函数。但由于我只是在开始我的 Haskell 方式,我不知道该怎么做。
首先,我定义了Insertion
、Table
并导入了Data.Char
:
type Insertion = (Char,Int)
type Table = [Insertion]
import Data.Char
然后我为 hist
实现了以下代码:
hist :: String -> Table
hist[] = []
hist(x:xs) = sortBy x (hist xs) where
sortBy x [] = [(x,1)]
sortBy x ((y,z):yzs)
| x == y = (y,z+1) : yzs
| otherwise = (y,z) : sortBy x yzs
还有这个给sort
:
sort :: Ord a => [a] -> [a]
sort [] = []
sort (x:xs) = paste x (sort xs)
paste :: Ord a => a -> [a] -> [a]
paste y [] = [y]
paste y (x:xs)
| x < y = x : paste y xs
| otherwise = y : x : xs
接下来我可以做什么?如何使用折叠功能来实现它们?
解决方法
列表中的
foldr f z
将列表 (:)
的“缺点”替换为 f
,将空列表 []
替换为 z
。
这意味着对于像 [1,4,2,5]
这样的列表,我们因此得到 f 1 (f 4 (f 2 (f 5 z)))
,因为 [1,5]
是 1 : 4 : 2 : 5 : []
或更规范的 (:) 1 ((:) 4 ((:) 2 ((:) 5 [])))
的缩写。
例如,sort
函数可以替换为折叠函数:
sort :: Ord a => [a] -> [a]
sort = foldr paste []
因为 sort [1,5]
等价于 paste 1 (paste 4 (paste 2 (paste 5 [])))
。此处 f
因此将元素作为第一个参数,并将对列表其余部分调用 foldr f z
的结果作为第二个参数,
我把 hist
留作练习。