module Proton.Feedback where
import Data.Profunctor
import Proton.Types
import Proton.Setter
import Data.Function
import Debug.Trace
type Feedback s t a b = forall p. Costrong p => p a b -> p s t
type Feedback' s a = Feedback s s a a
feedback :: forall p s t a b. Costrong p
=> ((s, b) -> a) -> (b -> (t, b)) -> Optic p s t a b
feedback :: ((s, b) -> a) -> (b -> (t, b)) -> Optic p s t a b
feedback ping :: (s, b) -> a
ping pong :: b -> (t, b)
pong = p (s, b) (t, b) -> p s t
forall (p :: * -> * -> *) a d b.
Costrong p =>
p (a, d) (b, d) -> p a b
unfirst (p (s, b) (t, b) -> p s t)
-> (p a b -> p (s, b) (t, b)) -> Optic p s t a b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((s, b) -> a) -> (b -> (t, b)) -> p a b -> p (s, b) (t, b)
forall (p :: * -> * -> *) a b c d.
Profunctor p =>
(a -> b) -> (c -> d) -> p b c -> p a d
dimap (s, b) -> a
ping b -> (t, b)
pong
fib :: Feedback Int [Int] [Int] [Int]
fib :: p [Int] [Int] -> p Int [Int]
fib = ((Int, [Int]) -> [Int])
-> ([Int] -> ([Int], [Int])) -> p [Int] [Int] -> p Int [Int]
forall (p :: * -> * -> *) s t a b.
Costrong p =>
((s, b) -> a) -> (b -> (t, b)) -> Optic p s t a b
feedback (Int, [Int]) -> [Int]
ping [Int] -> ([Int], [Int])
pong
where
ping :: ((Int, [Int]) -> [Int])
ping :: (Int, [Int]) -> [Int]
ping (n :: Int
n, xs :: [Int]
xs) = Int -> [Int] -> [Int]
forall a. Int -> [a] -> [a]
take Int
n [Int]
xs
pong :: [Int] -> ([Int], [Int])
pong :: [Int] -> ([Int], [Int])
pong xs :: [Int]
xs = ([Int] -> [Int]
forall a. [a] -> [a]
reverse [Int]
xs, [Int]
xs)