content: data MinHeap a = Nil | MinHeap { v::a, cnt::Int, l::MinHeap a, r::MinHeap a }
    deriving (Show, Eq)
  
  hPush :: (Ord a) => a -> MinHeap a -> MinHeap a
  hPush x Nil = MinHeap {v = x, cnt = 1, l = Nil, r = Nil}
  hPush x h = if x < vv -- insert element, try to keep the tree balanced
    then if hLength (l h) <= hLength (r h)
      then MinHeap { v=x, cnt=cc, l=hPush vv ll, r=rr }
      else MinHeap { v=x, cnt=cc, l=ll, r=hPush vv rr }
    else if hLength (l h) <= hLength (r h)
      then MinHeap { v=vv, cnt=cc, l=hPush x ll, r=rr }
      else MinHeap { v=vv, cnt=cc, l=ll, r=hPush x rr }
    where (vv, cc, ll, rr) = (v h, 1 + cnt h, l h, r h)
  
  hPop :: (Ord a) => MinHeap a -> (a, MinHeap a)
  hPop h = (v h, pq) where -- just pop, heed not the tree balance
    pq  | l h == Nil = r h
      | r h == Nil = l h
      | v (l h) <= v (r h) = let (vv,hh) = hPop (l h) in
        MinHeap {v = vv, cnt = hLength hh + hLength (r h),
          l = hh, r = r h}
      | otherwise = let (vv,hh) = hPop (r h) in
        MinHeap {v = vv, cnt = hLength hh + hLength (l h),
          l = l h, r = hh}
  
  hLength :: (Ord a) => MinHeap a -> Int
  hLength Nil = 0
  hLength h = cnt h
  
  hFromList :: (Ord a) => [a] -> MinHeap a
  hFromList = foldl (flip hPush) Nil
  
  hToList :: (Ord a) => MinHeap a -> [a]
  hToList = unfoldr f where
    f Nil = Nothing
    f h = Just $ hPop h
  
  main = mapM_ print $ hToList $ hFromList [
    (3, "Clear drains"),
    (4, "Feed cat"),
    (5, "Make tea"),
    (1, "Solve RC tasks"),
    (2, "Tax return")]
  