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)の方が、正確な気がするので好み