{- -----------------------------------------------------------------------------
Copyright 2019-2021 Kevin P. Barry

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.
----------------------------------------------------------------------------- -}

-- Author: Kevin P. Barry [ta0kira@gmail.com]

{-# LANGUAGE Safe #-}

module Types.Function (
  FunctionType(..),
  assignFunctionParams,
  checkFunctionConvert,
  validatateFunctionType,
) where

import Data.List (group,intercalate,sort)
import Control.Monad (when)
import qualified Data.Map as Map
import qualified Data.Set as Set

import Base.CompilerError
import Base.GeneralType
import Base.Positional
import Types.TypeInstance
import Types.Variance


data FunctionType =
  FunctionType {
    FunctionType -> Positional ValueType
ftArgs :: Positional ValueType,
    FunctionType -> Positional ValueType
ftReturns :: Positional ValueType,
    FunctionType -> Positional ParamName
ftParams :: Positional ParamName,
    FunctionType -> Positional [TypeFilter]
ftFilters :: Positional [TypeFilter]
  }
  deriving (FunctionType -> FunctionType -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: FunctionType -> FunctionType -> Bool
$c/= :: FunctionType -> FunctionType -> Bool
== :: FunctionType -> FunctionType -> Bool
$c== :: FunctionType -> FunctionType -> Bool
Eq)

instance Show FunctionType where
  show :: FunctionType -> String
show (FunctionType Positional ValueType
as Positional ValueType
rs Positional ParamName
ps Positional [TypeFilter]
fa) =
    String
"<" forall a. [a] -> [a] -> [a]
++ forall a. [a] -> [[a]] -> [a]
intercalate String
"," (forall a b. (a -> b) -> [a] -> [b]
map forall a. Show a => a -> String
show forall a b. (a -> b) -> a -> b
$ forall a. Positional a -> [a]
pValues Positional ParamName
ps) forall a. [a] -> [a] -> [a]
++ String
"> " forall a. [a] -> [a] -> [a]
++
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat (forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map forall {a} {a}. (Show a, Show a) => (a, [a]) -> [String]
showFilters forall a b. (a -> b) -> a -> b
$ forall a b. [a] -> [b] -> [(a, b)]
zip (forall a. Positional a -> [a]
pValues Positional ParamName
ps) (forall a. Positional a -> [a]
pValues Positional [TypeFilter]
fa)) forall a. [a] -> [a] -> [a]
++
    String
"(" forall a. [a] -> [a] -> [a]
++ forall a. [a] -> [[a]] -> [a]
intercalate String
"," (forall a b. (a -> b) -> [a] -> [b]
map forall a. Show a => a -> String
show forall a b. (a -> b) -> a -> b
$ forall a. Positional a -> [a]
pValues Positional ValueType
as) forall a. [a] -> [a] -> [a]
++ String
") -> " forall a. [a] -> [a] -> [a]
++
    String
"(" forall a. [a] -> [a] -> [a]
++ forall a. [a] -> [[a]] -> [a]
intercalate String
"," (forall a b. (a -> b) -> [a] -> [b]
map forall a. Show a => a -> String
show forall a b. (a -> b) -> a -> b
$ forall a. Positional a -> [a]
pValues Positional ValueType
rs) forall a. [a] -> [a] -> [a]
++ String
")"
    where
      showFilters :: (a, [a]) -> [String]
showFilters (a
n,[a]
fs) = forall a b. (a -> b) -> [a] -> [b]
map (\a
f -> forall a. Show a => a -> String
show a
n forall a. [a] -> [a] -> [a]
++ String
" " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show a
f forall a. [a] -> [a] -> [a]
++ String
" ") [a]
fs

validatateFunctionType :: (CollectErrorsM m, TypeResolver r) =>
  r -> Set.Set ParamName -> ParamVariances -> FunctionType -> m ()
validatateFunctionType :: forall (m :: * -> *) r.
(CollectErrorsM m, TypeResolver r) =>
r -> Set ParamName -> ParamVariances -> FunctionType -> m ()
validatateFunctionType r
r Set ParamName
params ParamVariances
vm (FunctionType Positional ValueType
as Positional ValueType
rs Positional ParamName
ps Positional [TypeFilter]
fa) = do
  forall (m :: * -> *) a b.
CollectErrorsM m =>
(a -> m b) -> [a] -> m ()
mapCompilerM_ forall {m :: * -> *} {a}. (ErrorContextM m, Show a) => [a] -> m ()
checkCount forall a b. (a -> b) -> a -> b
$ forall a. Eq a => [a] -> [[a]]
group forall a b. (a -> b) -> a -> b
$ forall a. Ord a => [a] -> [a]
sort forall a b. (a -> b) -> a -> b
$ forall a. Positional a -> [a]
pValues Positional ParamName
ps
  forall (m :: * -> *) a b.
CollectErrorsM m =>
(a -> m b) -> [a] -> m ()
mapCompilerM_ forall {f :: * -> *}. ErrorContextM f => ParamName -> f ()
checkHides forall a b. (a -> b) -> a -> b
$ forall a. Positional a -> [a]
pValues Positional ParamName
ps
  let allParams :: Set ParamName
allParams = forall a. Ord a => Set a -> Set a -> Set a
Set.union Set ParamName
params (forall a. Ord a => [a] -> Set a
Set.fromList forall a b. (a -> b) -> a -> b
$ forall a. Positional a -> [a]
pValues Positional ParamName
ps)
  [(ParamName, TypeFilter)]
expanded <- forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat forall a b. (a -> b) -> a -> b
$ forall a b (m :: * -> *) c.
(Show a, Show b, CollectErrorsM m) =>
(a -> b -> m c) -> Positional a -> Positional b -> m [c]
processPairs (\ParamName
n [TypeFilter]
fs -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b. [a] -> [b] -> [(a, b)]
zip (forall a. a -> [a]
repeat ParamName
n) [TypeFilter]
fs) Positional ParamName
ps Positional [TypeFilter]
fa
  forall (m :: * -> *) a b.
CollectErrorsM m =>
(a -> m b) -> [a] -> m ()
mapCompilerM_ (forall {m :: * -> *} {a}.
(CollectErrorsM m, Show a) =>
Set ParamName -> (a, TypeFilter) -> m ()
checkFilterType Set ParamName
allParams) [(ParamName, TypeFilter)]
expanded
  forall (m :: * -> *) a b.
CollectErrorsM m =>
(a -> m b) -> [a] -> m ()
mapCompilerM_ forall {m :: * -> *} {a}.
(CollectErrorsM m, Show a) =>
(a, TypeFilter) -> m ()
checkFilterVariance [(ParamName, TypeFilter)]
expanded
  forall (m :: * -> *) a b.
CollectErrorsM m =>
(a -> m b) -> [a] -> m ()
mapCompilerM_ (forall {m :: * -> *}.
CollectErrorsM m =>
Set ParamName -> ValueType -> m ()
checkArg Set ParamName
allParams) forall a b. (a -> b) -> a -> b
$ forall a. Positional a -> [a]
pValues Positional ValueType
as
  forall (m :: * -> *) a b.
CollectErrorsM m =>
(a -> m b) -> [a] -> m ()
mapCompilerM_ (forall {m :: * -> *}.
CollectErrorsM m =>
Set ParamName -> ValueType -> m ()
checkReturn Set ParamName
allParams) forall a b. (a -> b) -> a -> b
$ forall a. Positional a -> [a]
pValues Positional ValueType
rs
  where
    allVariances :: ParamVariances
allVariances = forall k a. Ord k => Map k a -> Map k a -> Map k a
Map.union ParamVariances
vm (forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList forall a b. (a -> b) -> a -> b
$ forall a b. [a] -> [b] -> [(a, b)]
zip (forall a. Positional a -> [a]
pValues Positional ParamName
ps) (forall a. a -> [a]
repeat Variance
Invariant))
    checkCount :: [a] -> m ()
checkCount xa :: [a]
xa@(a
x:a
_:[a]
_) =
      forall (m :: * -> *) a. ErrorContextM m => String -> m a
compilerErrorM forall a b. (a -> b) -> a -> b
$ String
"Function parameter " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show a
x forall a. [a] -> [a] -> [a]
++ String
" occurs " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show (forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
xa) forall a. [a] -> [a] -> [a]
++ String
" times"
    checkCount [a]
_ = forall (m :: * -> *) a. Monad m => a -> m a
return ()
    checkHides :: ParamName -> f ()
checkHides ParamName
n =
      forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (ParamName
n forall a. Ord a => a -> Set a -> Bool
`Set.member` Set ParamName
params) forall a b. (a -> b) -> a -> b
$
        forall (m :: * -> *) a. ErrorContextM m => String -> m a
compilerErrorM forall a b. (a -> b) -> a -> b
$ String
"Function parameter " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show ParamName
n forall a. [a] -> [a] -> [a]
++ String
" hides a category-level parameter"
    checkFilterType :: Set ParamName -> (a, TypeFilter) -> m ()
checkFilterType Set ParamName
fa2 (a
n,TypeFilter
f) =
      forall (m :: * -> *) r.
(CollectErrorsM m, TypeResolver r) =>
r -> Set ParamName -> TypeFilter -> m ()
validateTypeFilter r
r Set ParamName
fa2 TypeFilter
f forall (m :: * -> *) a. ErrorContextM m => m a -> String -> m a
<?? (String
"In filter " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show a
n forall a. [a] -> [a] -> [a]
++ String
" " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show TypeFilter
f)
    checkFilterVariance :: (a, TypeFilter) -> m ()
checkFilterVariance (a
n,f :: TypeFilter
f@(TypeFilter FilterDirection
FilterRequires GeneralInstance
t)) =
      forall (m :: * -> *) r.
(CollectErrorsM m, TypeResolver r) =>
r -> ParamVariances -> Variance -> GeneralInstance -> m ()
validateInstanceVariance r
r ParamVariances
allVariances Variance
Contravariant GeneralInstance
t forall (m :: * -> *) a. ErrorContextM m => m a -> String -> m a
<??
        (String
"In filter " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show a
n forall a. [a] -> [a] -> [a]
++ String
" " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show TypeFilter
f)
    checkFilterVariance (a
n,f :: TypeFilter
f@(TypeFilter FilterDirection
FilterAllows GeneralInstance
t)) =
      forall (m :: * -> *) r.
(CollectErrorsM m, TypeResolver r) =>
r -> ParamVariances -> Variance -> GeneralInstance -> m ()
validateInstanceVariance r
r ParamVariances
allVariances Variance
Covariant GeneralInstance
t forall (m :: * -> *) a. ErrorContextM m => m a -> String -> m a
<??
        (String
"In filter " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show a
n forall a. [a] -> [a] -> [a]
++ String
" " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show TypeFilter
f)
    checkFilterVariance (a
n,f :: TypeFilter
f@(DefinesFilter DefinesInstance
t)) =
      forall (m :: * -> *) r.
(CollectErrorsM m, TypeResolver r) =>
r -> ParamVariances -> Variance -> DefinesInstance -> m ()
validateDefinesVariance r
r ParamVariances
allVariances Variance
Contravariant DefinesInstance
t forall (m :: * -> *) a. ErrorContextM m => m a -> String -> m a
<??
        (String
"In filter " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show a
n forall a. [a] -> [a] -> [a]
++ String
" " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show TypeFilter
f)
    checkFilterVariance (a
_,TypeFilter
ImmutableFilter) = forall (m :: * -> *) a. Monad m => a -> m a
return ()
    checkArg :: Set ParamName -> ValueType -> m ()
checkArg Set ParamName
fa2 ta :: ValueType
ta@(ValueType StorageType
_ GeneralInstance
t) = (String
"In argument " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show ValueType
ta) forall (m :: * -> *) a. ErrorContextM m => String -> m a -> m a
??> do
      forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (ValueType -> Bool
isWeakValue ValueType
ta) forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. ErrorContextM m => String -> m a
compilerErrorM String
"Weak values not allowed as argument types"
      forall (m :: * -> *) r.
(CollectErrorsM m, TypeResolver r) =>
r -> Set ParamName -> GeneralInstance -> m ()
validateGeneralInstance r
r Set ParamName
fa2 GeneralInstance
t
      forall (m :: * -> *) r.
(CollectErrorsM m, TypeResolver r) =>
r -> ParamVariances -> Variance -> GeneralInstance -> m ()
validateInstanceVariance r
r ParamVariances
allVariances Variance
Contravariant GeneralInstance
t
    checkReturn :: Set ParamName -> ValueType -> m ()
checkReturn Set ParamName
fa2 ta :: ValueType
ta@(ValueType StorageType
_ GeneralInstance
t) = (String
"In return " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show ValueType
ta) forall (m :: * -> *) a. ErrorContextM m => String -> m a -> m a
??> do
      forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (ValueType -> Bool
isWeakValue ValueType
ta) forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. ErrorContextM m => String -> m a
compilerErrorM String
"Weak values not allowed as return types"
      forall (m :: * -> *) r.
(CollectErrorsM m, TypeResolver r) =>
r -> Set ParamName -> GeneralInstance -> m ()
validateGeneralInstance r
r Set ParamName
fa2 GeneralInstance
t
      forall (m :: * -> *) r.
(CollectErrorsM m, TypeResolver r) =>
r -> ParamVariances -> Variance -> GeneralInstance -> m ()
validateInstanceVariance r
r ParamVariances
allVariances Variance
Covariant GeneralInstance
t

assignFunctionParams :: (CollectErrorsM m, TypeResolver r) =>
  r -> ParamFilters -> ParamValues -> Positional GeneralInstance ->
  FunctionType -> m FunctionType
assignFunctionParams :: forall (m :: * -> *) r.
(CollectErrorsM m, TypeResolver r) =>
r
-> ParamFilters
-> ParamValues
-> Positional GeneralInstance
-> FunctionType
-> m FunctionType
assignFunctionParams r
r ParamFilters
fm ParamValues
pm Positional GeneralInstance
ts (FunctionType Positional ValueType
as Positional ValueType
rs Positional ParamName
ps Positional [TypeFilter]
fa) = do
  forall (m :: * -> *) a b.
CollectErrorsM m =>
(a -> m b) -> [a] -> m ()
mapCompilerM_ (forall (m :: * -> *) r.
(CollectErrorsM m, TypeResolver r) =>
r -> ParamFilters -> GeneralInstance -> m ()
validateGeneralInstanceForCall r
r ParamFilters
fm) forall a b. (a -> b) -> a -> b
$ forall a. Positional a -> [a]
pValues Positional GeneralInstance
ts
  ParamValues
assigned <- forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList forall a b. (a -> b) -> a -> b
$ forall a b (m :: * -> *) c.
(Show a, Show b, CollectErrorsM m) =>
(a -> b -> m c) -> Positional a -> Positional b -> m [c]
processPairs forall (m :: * -> *) a b. Monad m => a -> b -> m (a, b)
alwaysPair Positional ParamName
ps Positional GeneralInstance
ts
  let pa :: ParamValues
pa = ParamValues
pm forall k a. Ord k => Map k a -> Map k a -> Map k a
`Map.union` ParamValues
assigned
  Positional [TypeFilter]
fa' <- forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. [a] -> Positional a
Positional forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a b.
CollectErrorsM m =>
(a -> m b) -> [a] -> m [b]
mapCompilerM (forall {m :: * -> *}.
CollectErrorsM m =>
ParamValues -> [TypeFilter] -> m [TypeFilter]
assignFilters ParamValues
pa) (forall a. Positional a -> [a]
pValues Positional [TypeFilter]
fa)
  forall a b (m :: * -> *) c.
(Show a, Show b, CollectErrorsM m) =>
(a -> b -> m c) -> Positional a -> Positional b -> m ()
processPairs_ (forall (m :: * -> *) r.
(CollectErrorsM m, TypeResolver r) =>
r -> ParamFilters -> GeneralInstance -> [TypeFilter] -> m ()
validateAssignment r
r ParamFilters
fm) Positional GeneralInstance
ts Positional [TypeFilter]
fa'
  Positional ValueType
as' <- forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. [a] -> Positional a
Positional forall a b. (a -> b) -> a -> b
$
         forall (m :: * -> *) a b.
CollectErrorsM m =>
(a -> m b) -> [a] -> m [b]
mapCompilerM (forall (m :: * -> *).
CollectErrorsM m =>
(ParamName -> m GeneralInstance) -> ValueType -> m ValueType
uncheckedSubValueType forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
ErrorContextM m =>
ParamValues -> ParamName -> m GeneralInstance
getValueForParam ParamValues
pa) (forall a. Positional a -> [a]
pValues Positional ValueType
as)
  Positional ValueType
rs' <- forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. [a] -> Positional a
Positional forall a b. (a -> b) -> a -> b
$
         forall (m :: * -> *) a b.
CollectErrorsM m =>
(a -> m b) -> [a] -> m [b]
mapCompilerM (forall (m :: * -> *).
CollectErrorsM m =>
(ParamName -> m GeneralInstance) -> ValueType -> m ValueType
uncheckedSubValueType forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
ErrorContextM m =>
ParamValues -> ParamName -> m GeneralInstance
getValueForParam ParamValues
pa) (forall a. Positional a -> [a]
pValues Positional ValueType
rs)
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Positional ValueType
-> Positional ValueType
-> Positional ParamName
-> Positional [TypeFilter]
-> FunctionType
FunctionType Positional ValueType
as' Positional ValueType
rs' (forall a. [a] -> Positional a
Positional []) (forall a. [a] -> Positional a
Positional [])
  where
    assignFilters :: ParamValues -> [TypeFilter] -> m [TypeFilter]
assignFilters ParamValues
fm2 [TypeFilter]
fs = forall (m :: * -> *) a b.
CollectErrorsM m =>
(a -> m b) -> [a] -> m [b]
mapCompilerM (forall (m :: * -> *).
CollectErrorsM m =>
(ParamName -> m GeneralInstance) -> TypeFilter -> m TypeFilter
uncheckedSubFilter forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
ErrorContextM m =>
ParamValues -> ParamName -> m GeneralInstance
getValueForParam ParamValues
fm2) [TypeFilter]
fs

checkFunctionConvert :: (CollectErrorsM m, TypeResolver r) =>
  r -> ParamFilters -> ParamValues -> FunctionType -> FunctionType -> m ()
checkFunctionConvert :: forall (m :: * -> *) r.
(CollectErrorsM m, TypeResolver r) =>
r
-> ParamFilters
-> ParamValues
-> FunctionType
-> FunctionType
-> m ()
checkFunctionConvert r
r ParamFilters
fm ParamValues
pm (FunctionType Positional ValueType
as1 Positional ValueType
rs1 Positional ParamName
ps1 Positional [TypeFilter]
fa1) FunctionType
ff2 = do
  ParamFilters
mapped <- forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList forall a b. (a -> b) -> a -> b
$ forall a b (m :: * -> *) c.
(Show a, Show b, CollectErrorsM m) =>
(a -> b -> m c) -> Positional a -> Positional b -> m [c]
processPairs forall (m :: * -> *) a b. Monad m => a -> b -> m (a, b)
alwaysPair Positional ParamName
ps1 Positional [TypeFilter]
fa1
  let fm' :: ParamFilters
fm' = forall k a. Ord k => Map k a -> Map k a -> Map k a
Map.union ParamFilters
fm ParamFilters
mapped
  let asTypes :: Positional GeneralInstance
asTypes = forall a. [a] -> Positional a
Positional forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (forall a. (Eq a, Ord a) => a -> GeneralType a
singleType forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> ParamName -> TypeInstanceOrParam
JustParamName Bool
False) forall a b. (a -> b) -> a -> b
$ forall a. Positional a -> [a]
pValues Positional ParamName
ps1
  -- Substitute params from ff2 into ff1.
  (FunctionType Positional ValueType
as2 Positional ValueType
rs2 Positional ParamName
_ Positional [TypeFilter]
_) <- forall (m :: * -> *) r.
(CollectErrorsM m, TypeResolver r) =>
r
-> ParamFilters
-> ParamValues
-> Positional GeneralInstance
-> FunctionType
-> m FunctionType
assignFunctionParams r
r ParamFilters
fm' ParamValues
pm Positional GeneralInstance
asTypes FunctionType
ff2
  [(ParamName, [TypeFilter])]
fixed <- forall a b (m :: * -> *) c.
(Show a, Show b, CollectErrorsM m) =>
(a -> b -> m c) -> Positional a -> Positional b -> m [c]
processPairs forall (m :: * -> *) a b. Monad m => a -> b -> m (a, b)
alwaysPair Positional ParamName
ps1 Positional [TypeFilter]
fa1
  let fm'' :: ParamFilters
fm'' = forall k a. Ord k => Map k a -> Map k a -> Map k a
Map.union ParamFilters
fm (forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [(ParamName, [TypeFilter])]
fixed)
  forall a b (m :: * -> *) c.
(Show a, Show b, CollectErrorsM m) =>
(a -> b -> m c) -> Positional a -> Positional b -> m ()
processPairs_ (forall {m :: * -> *}.
CollectErrorsM m =>
ParamFilters -> ValueType -> ValueType -> m ()
validateArg ParamFilters
fm'') Positional ValueType
as1 Positional ValueType
as2
  forall a b (m :: * -> *) c.
(Show a, Show b, CollectErrorsM m) =>
(a -> b -> m c) -> Positional a -> Positional b -> m ()
processPairs_ (forall {m :: * -> *}.
CollectErrorsM m =>
ParamFilters -> ValueType -> ValueType -> m ()
validateReturn ParamFilters
fm'') Positional ValueType
rs1 Positional ValueType
rs2
  where
    validateArg :: ParamFilters -> ValueType -> ValueType -> m ()
validateArg ParamFilters
fm2 ValueType
a1 ValueType
a2 = forall (m :: * -> *) r.
(CollectErrorsM m, TypeResolver r) =>
r -> ParamFilters -> ValueType -> ValueType -> m ()
checkValueAssignment r
r ParamFilters
fm2 ValueType
a1 ValueType
a2
    validateReturn :: ParamFilters -> ValueType -> ValueType -> m ()
validateReturn ParamFilters
fm2 ValueType
r1 ValueType
r2 = forall (m :: * -> *) r.
(CollectErrorsM m, TypeResolver r) =>
r -> ParamFilters -> ValueType -> ValueType -> m ()
checkValueAssignment r
r ParamFilters
fm2 ValueType
r2 ValueType
r1