packages feed

proton-0.0.1: src/Data/Profunctor/Extraction.hs

module Data.Profunctor.Extraction where

import Data.Profunctor
import Control.Comonad
import Data.Distributive
import qualified Data.List.NonEmpty as NE
import Control.Comonad.Store
import Data.Pair

class Profunctor p => Extraction p where
  extractions :: Comonad w => p (w a) b -> p (w a) (w b)

instance Extraction (Forget r) where
  extractions (Forget f) = Forget f

instance Extraction (->) where
  extractions f = extend f

instance Distributive f => Extraction (Star f) where
  extractions (Star f) = Star (distribute . extend f)

act :: (Star f a b -> Star f s t) -> (a -> f b) -> s -> f t
act o f = runStar (o (Star f))

t :: (NE.NonEmpty a) -> Pair (Maybe a)
t (a NE.:| (b : _)) = Pair (Just a) (Just b)
t (a NE.:| _) = Pair (Just a) Nothing

u :: (NE.NonEmpty Int) -> Pair Int
u xs = Pair (sum xs) (NE.length xs)




-- thingy :: forall w a b. Comonad w => (a -> w (Either a b)) -> (w a -> w b)
-- thingy f = extend loop . fmap Left
--     where
--       loop :: w (Either a b) -> b
--       loop w = case extract w of
--           Left a' -> loop $ f a'
--           Right b -> b

home :: Int -> Store Int Int -> Either Int Int
home n s | extract s == n = Left $ pos s
  | abs (peeks (+1) s - n) < abs (peeks (subtract 1) s - n) = Right $ peeks (+1) s
  | otherwise = Right $ peeks (subtract 1) s

looper :: NE.NonEmpty Int -> Either [Int] Int
looper xs | sum xs > 10 = Left (NE.toList xs)
  | otherwise = Right $ (sum xs + 1)

coiterate :: forall w a b.
         (Traversable w, Comonad w)
         => (w a -> Either b a)
         -> (w a -> w b)
coiterate f = extend loop
    where
      loop :: w a -> b
      loop = either id loop . sequenceA . extend f

-- thingy :: (Choice p, Cochoice p) => p a (Either b a) -> p (w a) (w b)
-- thingy = _ . unright . _ . right'