generated at
Paramorphismの練習


『関数プログラミングの楽しみ』の3章の練習問題でParamorphismを使った書き直しがいくつか出てくるのでやってみてるが、割と難しい
Paramorphism foldr の強化版ということを捉えるのは大前提
その上で、
なぜ foldr では無理(あるいは複雑になる)で、 para では書けるのか、ということを考える
また、それはさておき、 para を使って書く時の考え方、というのをメモる


まずparaの定義
hs
para :: (a -> ([a], b) -> b) -> b -> [a] -> b para f z [] = z para f z (x : xs) = f x (xs, para f z xs)


Data.List.insert の再実装
こんな感じで書ける
hs
insertWithPara :: Ord a => a -> [a] -> [a] insertWithPara v = para f [] where f x (xs, ys) | v <= x = v:x:xs | otherwise = x:ys
この f がどういう関数なのか、というのを捉えるのがまず難しい
まず para foldr の強化版であることをまず抑える
foldl ではなく foldr である
f x (xs, ys) の理解
ys
accumratorとなるリスト
f が呼ばれた時点で ys は処理済になっている
x
currentとなる要素
xs
para 特有のもの
x:xs とすることで、 f が呼ばれた時点でのリストを再生できる
まだちゃんと捉えきれてない

あと、そもそもpara使わなくても以下のようにfoldrで書けるのでは
hs
insert' :: Ord a => a -> [a] -> [a] insert' v = foldr f [v] where f x (y:ys) | x <= y = x:y:ys | otherwise = y:x:ys
foldrにできなくて、paraでのみできることって何だっけ?


そもそもfoldr自体に捉えが甘いのと、
あるいはZygomorphismから取り組んでみる
というのはどうでしょう?

hs
deleteWithPara :: Ord a => a -> [a] -> [a] deleteWithPara v = para f [] where f x (xs, ys) | v == x = xs | otherwise = x:ys


hs
delmin :: Ord a => [a] -> Maybe (a, [a]) delmin = para f Nothing where f x (xs, Nothing) | null xs = Just (x, []) | otherwise = Just (x, xs) f x (xs, Just (min, ys)) | x <= min = Just (x, xs) | otherwise = Just (min, x : ys)