// Copyright (c) 2024 IBM Corp. // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package state import ( F "github.com/IBM/fp-go/function" P "github.com/IBM/fp-go/pair" ) func Of[ HKTSA ~func(S) HKTA, HKTA, S, A any, ]( fof func(P.Pair[A, S]) HKTA, a A) HKTSA { return F.Flow2( F.Bind1st(P.MakePair[A, S], a), fof, ) } func MonadMap[ HKTSA ~func(S) HKTA, HKTSB ~func(S) HKTB, HKTA, HKTB, S, A, B any, ]( fmap func(HKTA, func(P.Pair[A, S]) P.Pair[B, S]) HKTB, fa HKTSA, f func(A) B, ) HKTSB { return F.Flow2( fa, F.Bind2nd(fmap, P.Map[S](f)), ) } func Map[ HKTSA ~func(S) HKTA, HKTSB ~func(S) HKTB, HKTA, HKTB, S, A, B any, ]( fmap func(func(P.Pair[A, S]) P.Pair[B, S]) func(HKTA) HKTB, f func(A) B, ) func(HKTSA) HKTSB { mp := fmap(P.Map[S](f)) return func(fa HKTSA) HKTSB { return F.Flow2( fa, mp, ) } } func MonadChain[ HKTSA ~func(S) HKTA, HKTSB ~func(S) HKTB, HKTA, HKTB, S, A any, ]( fchain func(HKTA, func(P.Pair[A, S]) HKTB) HKTB, fa HKTSA, f func(A) HKTSB, ) HKTSB { return F.Flow2( fa, F.Bind2nd(fchain, func(a P.Pair[A, S]) HKTB { return f(P.Head(a))(P.Tail(a)) }), ) } func Chain[ HKTSA ~func(S) HKTA, HKTSB ~func(S) HKTB, HKTA, HKTB, S, A any, ]( fchain func(func(P.Pair[A, S]) HKTB) func(HKTA) HKTB, f func(A) HKTSB, ) func(HKTSA) HKTSB { mp := fchain(func(a P.Pair[A, S]) HKTB { return f(P.Head(a))(P.Tail(a)) }) return func(fa HKTSA) HKTSB { return F.Flow2( fa, mp, ) } } func MonadAp[ HKTSA ~func(S) HKTA, HKTSB ~func(S) HKTB, HKTSAB ~func(S) HKTAB, HKTA, HKTB, HKTAB, S, A, B any, ]( fmap func(HKTA, func(P.Pair[A, S]) P.Pair[B, S]) HKTB, fchain func(HKTAB, func(P.Pair[func(A) B, S]) HKTB) HKTB, fab HKTSAB, fa HKTSA, ) HKTSB { return func(s S) HKTB { return fchain(fab(s), func(ab P.Pair[func(A) B, S]) HKTB { return fmap(fa(P.Tail(ab)), P.Map[S](P.Head(ab))) }) } } func Ap[ HKTSA ~func(S) HKTA, HKTSB ~func(S) HKTB, HKTSAB ~func(S) HKTAB, HKTA, HKTB, HKTAB, S, A, B any, ]( fmap func(func(P.Pair[A, S]) P.Pair[B, S]) func(HKTA) HKTB, fchain func(func(P.Pair[func(A) B, S]) HKTB) func(HKTAB) HKTB, fa HKTSA, ) func(HKTSAB) HKTSB { return func(fab HKTSAB) HKTSB { return F.Flow2( fab, fchain(func(ab P.Pair[func(A) B, S]) HKTB { return fmap(P.Map[S](P.Head(ab)))(fa(P.Tail(ab))) }), ) } } func FromF[ HKTSA ~func(S) HKTA, HKTA, HKTFA, S, A any, ]( fmap func(HKTFA, func(A) P.Pair[A, S]) HKTA, ma HKTFA) HKTSA { f1 := F.Bind1st(fmap, ma) return func(s S) HKTA { return f1(F.Bind2nd(P.MakePair[A, S], s)) } } func FromState[ HKTSA ~func(S) HKTA, ST ~func(S) P.Pair[A, S], HKTA, S, A any, ]( fof func(P.Pair[A, S]) HKTA, sa ST, ) HKTSA { return F.Flow2(sa, fof) }