unfold
unfoldrとか使ったことないのが敗因な気が
import Data.List(unfoldr) --hoge = [0..] hoge = unfoldr (\x -> Just (x,x+1)) 0 --huga = [0,1,2,3,4,5,6,7,8,9] huga = unfoldr (\x -> (if (x <10) then Just (x,x+1) else Nothing)) 0 --leibnitz inifinity = pi leibnitz k = (4*) $ sum $ take k $ unfoldr (\n -> Just (fromInteger(2-(mod n 4))/(fromInteger n) , n+2)) 1
なんかよくわからん。何かデータのリストなり集合なりを受け取って、binary treeを構築するみたいな処理はありがちだけど、そういうので使えばいいのかな
data BTree a b = Leaf b | Node a (BTree a b) (BTree a b) unfoldT :: (x -> Either b (a,x,x)) -> x -> BTree a b unfoldT f init = case (f init) of Left x -> Leaf x Right (n,l,r) -> Node n (unfoldT f l) (unfoldT f r) instance (Show a , Show b) => Show (BTree a b) where show (Leaf x) = show(x) show (Node n x y) = "(" ++ (show n) ++ " " ++ (show x) ++ " " ++ (show y) ++")" ex::(Ord a) => [a] -> (BTree a ()) ex _L = unfoldT sub _L where sub x = case x of [] -> (Left ()) x:xs -> Right (x , filter (x<=) xs , filter (x>) xs) main = print (ex [12,3,4,5,21,5,40,10,2])
というようなことを書いてて思ったこと。
・fold/buildルールみたいなのは、単一のデータ構造の中でグネグネしてるだけなので、異なるデータ型をつなぐ何かがないとダメっぽい
・fold/unfoldで、それなりに強力なループ処理が実現できるけど、こいつらって、どれくらい強力なんだろう
・Maybe (a,b)よりもEither () (a,b)の方が、正確な気がするので好み