{-# LANGUAGE GADTs #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
module Langchain.Runnable.Chain
(
RunnableBranch (..)
, RunnableMap (..)
, RunnableSequence
, runBranch
, runMap
, runSequence
, chain
, branch
, buildSequence
, appendSequence
, (|>>)
) where
import Data.List (find)
import Langchain.Runnable.Core
chain ::
(Runnable r1, Runnable r2, RunnableOutput r1 ~ RunnableInput r2) =>
r1 ->
r2 ->
RunnableInput r1 ->
IO (Either String (RunnableOutput r2))
chain :: forall r1 r2.
(Runnable r1, Runnable r2, RunnableOutput r1 ~ RunnableInput r2) =>
r1
-> r2 -> RunnableInput r1 -> IO (Either String (RunnableOutput r2))
chain r1
r1 r2
r2 RunnableInput r1
input = do
Either String (RunnableInput r2)
output1 <- r1 -> RunnableInput r1 -> IO (Either String (RunnableOutput r1))
forall r.
Runnable r =>
r -> RunnableInput r -> IO (Either String (RunnableOutput r))
invoke r1
r1 RunnableInput r1
input
case Either String (RunnableInput r2)
output1 of
Left String
err -> Either String (RunnableOutput r2)
-> IO (Either String (RunnableOutput r2))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either String (RunnableOutput r2)
-> IO (Either String (RunnableOutput r2)))
-> Either String (RunnableOutput r2)
-> IO (Either String (RunnableOutput r2))
forall a b. (a -> b) -> a -> b
$ String -> Either String (RunnableOutput r2)
forall a b. a -> Either a b
Left String
err
Right RunnableInput r2
intermediate -> r2 -> RunnableInput r2 -> IO (Either String (RunnableOutput r2))
forall r.
Runnable r =>
r -> RunnableInput r -> IO (Either String (RunnableOutput r))
invoke r2
r2 RunnableInput r2
intermediate
branch ::
(Runnable r1, Runnable r2, a ~ RunnableInput r1, a ~ RunnableInput r2) =>
r1 ->
r2 ->
a ->
IO (Either String (RunnableOutput r1, RunnableOutput r2))
branch :: forall r1 r2 a.
(Runnable r1, Runnable r2, a ~ RunnableInput r1,
a ~ RunnableInput r2) =>
r1
-> r2
-> a
-> IO (Either String (RunnableOutput r1, RunnableOutput r2))
branch r1
r1 r2
r2 a
input = do
Either String (RunnableOutput r1)
result1 <- r1 -> RunnableInput r1 -> IO (Either String (RunnableOutput r1))
forall r.
Runnable r =>
r -> RunnableInput r -> IO (Either String (RunnableOutput r))
invoke r1
r1 a
RunnableInput r1
input
Either String (RunnableOutput r2)
result2 <- r2 -> RunnableInput r2 -> IO (Either String (RunnableOutput r2))
forall r.
Runnable r =>
r -> RunnableInput r -> IO (Either String (RunnableOutput r))
invoke r2
r2 a
RunnableInput r2
input
Either String (RunnableOutput r1, RunnableOutput r2)
-> IO (Either String (RunnableOutput r1, RunnableOutput r2))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either String (RunnableOutput r1, RunnableOutput r2)
-> IO (Either String (RunnableOutput r1, RunnableOutput r2)))
-> Either String (RunnableOutput r1, RunnableOutput r2)
-> IO (Either String (RunnableOutput r1, RunnableOutput r2))
forall a b. (a -> b) -> a -> b
$ (,) (RunnableOutput r1
-> RunnableOutput r2 -> (RunnableOutput r1, RunnableOutput r2))
-> Either String (RunnableOutput r1)
-> Either
String
(RunnableOutput r2 -> (RunnableOutput r1, RunnableOutput r2))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Either String (RunnableOutput r1)
result1 Either
String
(RunnableOutput r2 -> (RunnableOutput r1, RunnableOutput r2))
-> Either String (RunnableOutput r2)
-> Either String (RunnableOutput r1, RunnableOutput r2)
forall a b.
Either String (a -> b) -> Either String a -> Either String b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Either String (RunnableOutput r2)
result2
data RunnableBranch a b
= forall r.
(Runnable r, RunnableInput r ~ a, RunnableOutput r ~ b) =>
RunnableBranch [(a -> Bool, r)] r
runBranch :: RunnableBranch a b -> a -> IO (Either String b)
runBranch :: forall a b. RunnableBranch a b -> a -> IO (Either String b)
runBranch (RunnableBranch [(a -> Bool, r)]
options r
defaultR) a
input =
case ((a -> Bool, r) -> Bool)
-> [(a -> Bool, r)] -> Maybe (a -> Bool, r)
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find (\(a -> Bool
cond, r
_) -> a -> Bool
cond a
input) [(a -> Bool, r)]
options of
Just (a -> Bool
_, r
r) -> r -> RunnableInput r -> IO (Either String (RunnableOutput r))
forall r.
Runnable r =>
r -> RunnableInput r -> IO (Either String (RunnableOutput r))
invoke r
r a
RunnableInput r
input
Maybe (a -> Bool, r)
Nothing -> r -> RunnableInput r -> IO (Either String (RunnableOutput r))
forall r.
Runnable r =>
r -> RunnableInput r -> IO (Either String (RunnableOutput r))
invoke r
defaultR a
RunnableInput r
input
instance Runnable (RunnableBranch a b) where
type RunnableInput (RunnableBranch a b) = a
type RunnableOutput (RunnableBranch a b) = b
invoke :: RunnableBranch a b
-> RunnableInput (RunnableBranch a b)
-> IO (Either String (RunnableOutput (RunnableBranch a b)))
invoke = RunnableBranch a b -> a -> IO (Either String b)
RunnableBranch a b
-> RunnableInput (RunnableBranch a b)
-> IO (Either String (RunnableOutput (RunnableBranch a b)))
forall a b. RunnableBranch a b -> a -> IO (Either String b)
runBranch
data RunnableMap a b c
= forall r.
(Runnable r, RunnableInput r ~ b, RunnableOutput r ~ c) =>
RunnableMap (a -> b) (c -> c) r
runMap :: RunnableMap a b c -> a -> IO (Either String c)
runMap :: forall a b c. RunnableMap a b c -> a -> IO (Either String c)
runMap (RunnableMap a -> b
inputFn c -> c
outputFn r
r) a
input = do
Either String c
result <- r -> RunnableInput r -> IO (Either String (RunnableOutput r))
forall r.
Runnable r =>
r -> RunnableInput r -> IO (Either String (RunnableOutput r))
invoke r
r (a -> b
inputFn a
input)
Either String c -> IO (Either String c)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either String c -> IO (Either String c))
-> Either String c -> IO (Either String c)
forall a b. (a -> b) -> a -> b
$ (c -> c) -> Either String c -> Either String c
forall a b. (a -> b) -> Either String a -> Either String b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap c -> c
outputFn Either String c
result
instance Runnable (RunnableMap a b c) where
type RunnableInput (RunnableMap a b c) = a
type RunnableOutput (RunnableMap a b c) = c
invoke :: RunnableMap a b c
-> RunnableInput (RunnableMap a b c)
-> IO (Either String (RunnableOutput (RunnableMap a b c)))
invoke = RunnableMap a b c -> a -> IO (Either String c)
RunnableMap a b c
-> RunnableInput (RunnableMap a b c)
-> IO (Either String (RunnableOutput (RunnableMap a b c)))
forall a b c. RunnableMap a b c -> a -> IO (Either String c)
runMap
data RunnableSequence a b where
RSNil :: RunnableSequence a a
RSCons ::
(Runnable r, RunnableInput r ~ a, RunnableOutput r ~ c) =>
r ->
RunnableSequence c b ->
RunnableSequence a b
runSequence :: RunnableSequence a b -> RunnableInputHead a -> IO (Either String b)
runSequence :: forall a b. RunnableSequence a b -> a -> IO (Either String b)
runSequence RunnableSequence a b
RSNil a
input = Either String b -> IO (Either String b)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (b -> Either String b
forall a b. b -> Either a b
Right a
b
input)
runSequence (RSCons r
r RunnableSequence c b
rs) a
input = do
Either String c
result <- r -> RunnableInput r -> IO (Either String (RunnableOutput r))
forall r.
Runnable r =>
r -> RunnableInput r -> IO (Either String (RunnableOutput r))
invoke r
r a
RunnableInput r
input
case Either String c
result of
Left String
err -> Either String b -> IO (Either String b)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> Either String b
forall a b. a -> Either a b
Left String
err)
Right c
out -> RunnableSequence c b -> c -> IO (Either String b)
forall a b. RunnableSequence a b -> a -> IO (Either String b)
runSequence RunnableSequence c b
rs c
out
instance Runnable (RunnableSequence a b) where
type RunnableInput (RunnableSequence a b) = a
type RunnableOutput (RunnableSequence a b) = b
invoke :: RunnableSequence a b
-> RunnableInput (RunnableSequence a b)
-> IO (Either String (RunnableOutput (RunnableSequence a b)))
invoke = RunnableSequence a b -> a -> IO (Either String b)
RunnableSequence a b
-> RunnableInput (RunnableSequence a b)
-> IO (Either String (RunnableOutput (RunnableSequence a b)))
forall a b. RunnableSequence a b -> a -> IO (Either String b)
runSequence
type RunnableInputHead a = a
buildSequence ::
( Runnable r1
, Runnable r2
, RunnableOutput r1 ~ RunnableInput r2
) =>
r1 ->
r2 ->
RunnableSequence (RunnableInput r1) (RunnableOutput r2)
buildSequence :: forall r1 r2.
(Runnable r1, Runnable r2, RunnableOutput r1 ~ RunnableInput r2) =>
r1 -> r2 -> RunnableSequence (RunnableInput r1) (RunnableOutput r2)
buildSequence r1
r1 r2
r2 = r1
-> RunnableSequence (RunnableInput r2) (RunnableOutput r2)
-> RunnableSequence (RunnableInput r1) (RunnableOutput r2)
forall r a c b.
(Runnable r, RunnableInput r ~ a, RunnableOutput r ~ c) =>
r -> RunnableSequence c b -> RunnableSequence a b
RSCons r1
r1 (r2
-> RunnableSequence (RunnableOutput r2) (RunnableOutput r2)
-> RunnableSequence (RunnableInput r2) (RunnableOutput r2)
forall r a c b.
(Runnable r, RunnableInput r ~ a, RunnableOutput r ~ c) =>
r -> RunnableSequence c b -> RunnableSequence a b
RSCons r2
r2 RunnableSequence (RunnableOutput r2) (RunnableOutput r2)
forall a. RunnableSequence a a
RSNil)
appendSequence ::
( Runnable r2
, RunnableOutput (RunnableSequence a b) ~ (RunnableInput r2)
) =>
RunnableSequence a b ->
r2 ->
RunnableSequence a (RunnableOutput r2)
appendSequence :: forall r2 a b.
(Runnable r2,
RunnableOutput (RunnableSequence a b) ~ RunnableInput r2) =>
RunnableSequence a b
-> r2 -> RunnableSequence a (RunnableOutput r2)
appendSequence RunnableSequence a b
RSNil r2
r = r2
-> RunnableSequence (RunnableOutput r2) (RunnableOutput r2)
-> RunnableSequence a (RunnableOutput r2)
forall r a c b.
(Runnable r, RunnableInput r ~ a, RunnableOutput r ~ c) =>
r -> RunnableSequence c b -> RunnableSequence a b
RSCons r2
r RunnableSequence (RunnableOutput r2) (RunnableOutput r2)
forall a. RunnableSequence a a
RSNil
appendSequence (RSCons r
r1 RunnableSequence c b
rs) r2
r2 = r
-> RunnableSequence c (RunnableOutput r2)
-> RunnableSequence a (RunnableOutput r2)
forall r a c b.
(Runnable r, RunnableInput r ~ a, RunnableOutput r ~ c) =>
r -> RunnableSequence c b -> RunnableSequence a b
RSCons r
r1 (RunnableSequence c b
-> r2 -> RunnableSequence c (RunnableOutput r2)
forall r2 a b.
(Runnable r2,
RunnableOutput (RunnableSequence a b) ~ RunnableInput r2) =>
RunnableSequence a b
-> r2 -> RunnableSequence a (RunnableOutput r2)
appendSequence RunnableSequence c b
rs r2
r2)
(|>>) ::
(Runnable r1, Runnable r2, RunnableOutput r1 ~ RunnableInput r2) =>
r1 ->
r2 ->
RunnableInput r1 ->
IO (Either String (RunnableOutput r2))
|>> :: forall r1 r2.
(Runnable r1, Runnable r2, RunnableOutput r1 ~ RunnableInput r2) =>
r1
-> r2 -> RunnableInput r1 -> IO (Either String (RunnableOutput r2))
(|>>) = r1
-> r2 -> RunnableInput r1 -> IO (Either String (RunnableOutput r2))
forall r1 r2.
(Runnable r1, Runnable r2, RunnableOutput r1 ~ RunnableInput r2) =>
r1
-> r2 -> RunnableInput r1 -> IO (Either String (RunnableOutput r2))
chain
infix 4 |>>