{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TupleSections #-}
module Codec.Candid.Infer where

import qualified Data.Vector as V
import Control.Monad
import Data.Void
import Data.List
import Prettyprinter

import Codec.Candid.Types

inferTypes :: [Value] -> Either String [Type Void]
inferTypes :: [Value] -> Either String [Type Void]
inferTypes = (Value -> Either String (Type Void))
-> [Value] -> Either String [Type Void]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Value -> Either String (Type Void)
inferTyp

inferTyp :: Value -> Either String (Type Void)
inferTyp :: Value -> Either String (Type Void)
inferTyp (NumV Scientific
v) = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return (Type Void -> Either String (Type Void))
-> Type Void -> Either String (Type Void)
forall a b. (a -> b) -> a -> b
$ if Scientific
v Scientific -> Scientific -> Bool
forall a. Ord a => a -> a -> Bool
>= Scientific
0 then Type Void
forall a. Type a
NatT else Type Void
forall a. Type a
IntT
inferTyp (BoolV Bool
_) = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return Type Void
forall a. Type a
BoolT
inferTyp (NatV Natural
_) = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return Type Void
forall a. Type a
NatT
inferTyp (Nat8V Word8
_) = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return Type Void
forall a. Type a
Nat8T
inferTyp (Nat16V Word16
_) = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return Type Void
forall a. Type a
Nat16T
inferTyp (Nat32V Word32
_) = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return Type Void
forall a. Type a
Nat32T
inferTyp (Nat64V Word64
_) = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return Type Void
forall a. Type a
Nat64T
inferTyp (IntV Integer
_) = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return Type Void
forall a. Type a
IntT
inferTyp (Int8V Int8
_) = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return Type Void
forall a. Type a
Int8T
inferTyp (Int16V Int16
_) = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return Type Void
forall a. Type a
Int16T
inferTyp (Int32V Int32
_) = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return Type Void
forall a. Type a
Int32T
inferTyp (Int64V Int64
_) = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return Type Void
forall a. Type a
Int64T
inferTyp (Float32V Float
_) = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return Type Void
forall a. Type a
Float32T
inferTyp (Float64V Double
_) = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return Type Void
forall a. Type a
Float64T
inferTyp (TextV Text
_) = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return Type Void
forall a. Type a
TextT
inferTyp Value
NullV = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return Type Void
forall a. Type a
NullT
inferTyp Value
ReservedV = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return Type Void
forall a. Type a
ReservedT
inferTyp (OptV Maybe Value
Nothing) = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return (Type Void -> Either String (Type Void))
-> Type Void -> Either String (Type Void)
forall a b. (a -> b) -> a -> b
$ Type Void -> Type Void
forall a. Type a -> Type a
OptT Type Void
forall a. Type a
EmptyT
inferTyp (OptV (Just Value
v)) = Type Void -> Type Void
forall a. Type a -> Type a
OptT (Type Void -> Type Void)
-> Either String (Type Void) -> Either String (Type Void)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Either String (Type Void)
inferTyp Value
v
inferTyp (RepeatV Int
_ Value
v) = Type Void -> Type Void
forall a. Type a -> Type a
VecT (Type Void -> Type Void)
-> Either String (Type Void) -> Either String (Type Void)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Either String (Type Void)
inferTyp Value
v
inferTyp (VecV Vector Value
vs) = Type Void -> Type Void
forall a. Type a -> Type a
VecT (Type Void -> Type Void)
-> Either String (Type Void) -> Either String (Type Void)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((Value -> Either String (Type Void))
-> [Value] -> Either String [Type Void]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Value -> Either String (Type Void)
inferTyp (Vector Value -> [Value]
forall a. Vector a -> [a]
V.toList Vector Value
vs) Either String [Type Void]
-> ([Type Void] -> Either String (Type Void))
-> Either String (Type Void)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= [Type Void] -> Either String (Type Void)
lubs)
inferTyp (RecV [(FieldName, Value)]
fs) = Fields Void -> Type Void
forall a. Fields a -> Type a
RecT (Fields Void -> Type Void)
-> Either String (Fields Void) -> Either String (Type Void)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Either String (FieldName, Type Void)]
-> Either String (Fields Void)
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence [ (FieldName
fn,) (Type Void -> (FieldName, Type Void))
-> Either String (Type Void)
-> Either String (FieldName, Type Void)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Either String (Type Void)
inferTyp Value
t | (FieldName
fn, Value
t) <- [(FieldName, Value)]
fs ]
inferTyp (VariantV FieldName
f Value
v) = do
    Type Void
t <- Value -> Either String (Type Void)
inferTyp Value
v
    Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return (Type Void -> Either String (Type Void))
-> Type Void -> Either String (Type Void)
forall a b. (a -> b) -> a -> b
$ Fields Void -> Type Void
forall a. Fields a -> Type a
VariantT [ (FieldName
f, Type Void
t) ]
inferTyp (TupV [Value]
vs) = [Type Void] -> Type Void
forall a. [Type a] -> Type a
tupT ([Type Void] -> Type Void)
-> Either String [Type Void] -> Either String (Type Void)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Value -> Either String (Type Void))
-> [Value] -> Either String [Type Void]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Value -> Either String (Type Void)
inferTyp [Value]
vs
inferTyp (FuncV Principal
_ Text
_) = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return (MethodType Void -> Type Void
forall a. MethodType a -> Type a
FuncT ([Type Void]
-> [Type Void] -> Bool -> Bool -> Bool -> MethodType Void
forall a.
[Type a] -> [Type a] -> Bool -> Bool -> Bool -> MethodType a
MethodType [] [] Bool
False Bool
False Bool
False)) -- no principal type
inferTyp (ServiceV Principal
_) = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return ([(Text, MethodType Void)] -> Type Void
forall a. [(Text, MethodType a)] -> Type a
ServiceT []) -- no principal type
inferTyp (PrincipalV Principal
_) = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return Type Void
forall a. Type a
PrincipalT
inferTyp Value
FutureV = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return Type Void
forall a. Type a
FutureT
inferTyp (BlobV ByteString
_) = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return Type Void
forall a. Type a
BlobT
inferTyp (AnnV Value
_ Type Void
t) = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return Type Void
t -- Maybe do type checking?

lubs :: [Type Void] -> Either String (Type Void)
lubs :: [Type Void] -> Either String (Type Void)
lubs = (Type Void -> Type Void -> Either String (Type Void))
-> Type Void -> [Type Void] -> Either String (Type Void)
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM Type Void -> Type Void -> Either String (Type Void)
lub Type Void
forall a. Type a
EmptyT

lub :: Type Void -> Type Void -> Either String (Type Void)
lub :: Type Void -> Type Void -> Either String (Type Void)
lub Type Void
ReservedT Type Void
_ = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return Type Void
forall a. Type a
ReservedT
lub Type Void
_ Type Void
ReservedT = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return Type Void
forall a. Type a
ReservedT
lub Type Void
EmptyT Type Void
t = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return Type Void
t
lub Type Void
t Type Void
EmptyT = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return Type Void
t
lub Type Void
NatT Type Void
IntT = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return Type Void
forall a. Type a
IntT
lub Type Void
IntT Type Void
NatT = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return Type Void
forall a. Type a
IntT
lub Type Void
NullT (OptT Type Void
t) = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return (Type Void -> Type Void
forall a. Type a -> Type a
OptT Type Void
t)
lub (OptT Type Void
t) Type Void
NullT = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return (Type Void -> Type Void
forall a. Type a -> Type a
OptT Type Void
t)
lub (OptT Type Void
t1) (OptT Type Void
t2) = Type Void -> Type Void
forall a. Type a -> Type a
OptT (Type Void -> Type Void)
-> Either String (Type Void) -> Either String (Type Void)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Type Void -> Type Void -> Either String (Type Void)
lub Type Void
t1 Type Void
t2
lub (VecT Type Void
t1) (VecT Type Void
t2) = Type Void -> Type Void
forall a. Type a -> Type a
VecT (Type Void -> Type Void)
-> Either String (Type Void) -> Either String (Type Void)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Type Void -> Type Void -> Either String (Type Void)
lub Type Void
t1 Type Void
t2
lub (RecT Fields Void
fs1) (RecT Fields Void
fs2) = Fields Void -> Type Void
forall a. Fields a -> Type a
RecT (Fields Void -> Type Void)
-> Either String (Fields Void) -> Either String (Type Void)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Fields Void -> Fields Void -> Either String (Fields Void)
forall t.
Ord t =>
[(t, Type Void)]
-> [(t, Type Void)] -> Either String [(t, Type Void)]
go (((FieldName, Type Void) -> FieldName) -> Fields Void -> Fields Void
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn (FieldName, Type Void) -> FieldName
forall a b. (a, b) -> a
fst Fields Void
fs1) (((FieldName, Type Void) -> FieldName) -> Fields Void -> Fields Void
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn (FieldName, Type Void) -> FieldName
forall a b. (a, b) -> a
fst Fields Void
fs2)
  where
    go :: [(t, Type Void)]
-> [(t, Type Void)] -> Either String [(t, Type Void)]
go [] [(t, Type Void)]
_ = [(t, Type Void)] -> Either String [(t, Type Void)]
forall (m :: * -> *) a. Monad m => a -> m a
return []
    go [(t, Type Void)]
_ [] = [(t, Type Void)] -> Either String [(t, Type Void)]
forall (m :: * -> *) a. Monad m => a -> m a
return []
    go ((t
f1, Type Void
v1):[(t, Type Void)]
fs1) ((t
f2,Type Void
v2):[(t, Type Void)]
fs2)
        | t
f1 t -> t -> Bool
forall a. Ord a => a -> a -> Bool
< t
f2   = [(t, Type Void)]
-> [(t, Type Void)] -> Either String [(t, Type Void)]
go [(t, Type Void)]
fs1 ((t
f2,Type Void
v2)(t, Type Void) -> [(t, Type Void)] -> [(t, Type Void)]
forall a. a -> [a] -> [a]
:[(t, Type Void)]
fs2)
        | t
f1 t -> t -> Bool
forall a. Ord a => a -> a -> Bool
> t
f2   = [(t, Type Void)]
-> [(t, Type Void)] -> Either String [(t, Type Void)]
go ((t
f1,Type Void
v1)(t, Type Void) -> [(t, Type Void)] -> [(t, Type Void)]
forall a. a -> [a] -> [a]
:[(t, Type Void)]
fs1) [(t, Type Void)]
fs2
        | Bool
otherwise = (:) ((t, Type Void) -> [(t, Type Void)] -> [(t, Type Void)])
-> Either String (t, Type Void)
-> Either String ([(t, Type Void)] -> [(t, Type Void)])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((t
f1,) (Type Void -> (t, Type Void))
-> Either String (Type Void) -> Either String (t, Type Void)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Type Void -> Type Void -> Either String (Type Void)
lub Type Void
v1 Type Void
v2) Either String ([(t, Type Void)] -> [(t, Type Void)])
-> Either String [(t, Type Void)] -> Either String [(t, Type Void)]
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> [(t, Type Void)]
-> [(t, Type Void)] -> Either String [(t, Type Void)]
go [(t, Type Void)]
fs1 [(t, Type Void)]
fs2
lub (VariantT Fields Void
fs1) (VariantT Fields Void
fs2) = Fields Void -> Type Void
forall a. Fields a -> Type a
VariantT (Fields Void -> Type Void)
-> Either String (Fields Void) -> Either String (Type Void)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Fields Void -> Fields Void -> Either String (Fields Void)
forall t.
Ord t =>
[(t, Type Void)]
-> [(t, Type Void)] -> Either String [(t, Type Void)]
go (((FieldName, Type Void) -> FieldName) -> Fields Void -> Fields Void
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn (FieldName, Type Void) -> FieldName
forall a b. (a, b) -> a
fst Fields Void
fs1) (((FieldName, Type Void) -> FieldName) -> Fields Void -> Fields Void
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn (FieldName, Type Void) -> FieldName
forall a b. (a, b) -> a
fst Fields Void
fs2)
  where
    go :: [(t, Type Void)]
-> [(t, Type Void)] -> Either String [(t, Type Void)]
go [] [(t, Type Void)]
fs = [(t, Type Void)] -> Either String [(t, Type Void)]
forall (m :: * -> *) a. Monad m => a -> m a
return [(t, Type Void)]
fs
    go [(t, Type Void)]
fs [] = [(t, Type Void)] -> Either String [(t, Type Void)]
forall (m :: * -> *) a. Monad m => a -> m a
return [(t, Type Void)]
fs
    go ((t
f1, Type Void
v1):[(t, Type Void)]
fs1) ((t
f2,Type Void
v2):[(t, Type Void)]
fs2)
        | t
f1 t -> t -> Bool
forall a. Ord a => a -> a -> Bool
< t
f2   = ((t
f1,Type Void
v1) (t, Type Void) -> [(t, Type Void)] -> [(t, Type Void)]
forall a. a -> [a] -> [a]
:) ([(t, Type Void)] -> [(t, Type Void)])
-> Either String [(t, Type Void)] -> Either String [(t, Type Void)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [(t, Type Void)]
-> [(t, Type Void)] -> Either String [(t, Type Void)]
go [(t, Type Void)]
fs1 ((t
f2,Type Void
v2)(t, Type Void) -> [(t, Type Void)] -> [(t, Type Void)]
forall a. a -> [a] -> [a]
:[(t, Type Void)]
fs2)
        | t
f1 t -> t -> Bool
forall a. Ord a => a -> a -> Bool
> t
f2   = ((t
f2,Type Void
v2) (t, Type Void) -> [(t, Type Void)] -> [(t, Type Void)]
forall a. a -> [a] -> [a]
:) ([(t, Type Void)] -> [(t, Type Void)])
-> Either String [(t, Type Void)] -> Either String [(t, Type Void)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [(t, Type Void)]
-> [(t, Type Void)] -> Either String [(t, Type Void)]
go ((t
f1,Type Void
v1)(t, Type Void) -> [(t, Type Void)] -> [(t, Type Void)]
forall a. a -> [a] -> [a]
:[(t, Type Void)]
fs1) [(t, Type Void)]
fs2
        | Bool
otherwise = (:) ((t, Type Void) -> [(t, Type Void)] -> [(t, Type Void)])
-> Either String (t, Type Void)
-> Either String ([(t, Type Void)] -> [(t, Type Void)])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((t
f1,) (Type Void -> (t, Type Void))
-> Either String (Type Void) -> Either String (t, Type Void)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Type Void -> Type Void -> Either String (Type Void)
lub Type Void
v1 Type Void
v2) Either String ([(t, Type Void)] -> [(t, Type Void)])
-> Either String [(t, Type Void)] -> Either String [(t, Type Void)]
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> [(t, Type Void)]
-> [(t, Type Void)] -> Either String [(t, Type Void)]
go [(t, Type Void)]
fs1 [(t, Type Void)]
fs2

-- the reflexive cases
lub Type Void
NatT Type Void
NatT = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return Type Void
forall a. Type a
NatT
lub Type Void
Nat8T Type Void
Nat8T = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return Type Void
forall a. Type a
Nat8T
lub Type Void
Nat16T Type Void
Nat16T = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return Type Void
forall a. Type a
Nat16T
lub Type Void
Nat32T Type Void
Nat32T = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return Type Void
forall a. Type a
Nat32T
lub Type Void
Nat64T Type Void
Nat64T = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return Type Void
forall a. Type a
Nat64T
lub Type Void
IntT Type Void
IntT = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return Type Void
forall a. Type a
IntT
lub Type Void
Int8T Type Void
Int8T = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return Type Void
forall a. Type a
Int8T
lub Type Void
Int16T Type Void
Int16T = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return Type Void
forall a. Type a
Int16T
lub Type Void
Int32T Type Void
Int32T = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return Type Void
forall a. Type a
Int32T
lub Type Void
Int64T Type Void
Int64T = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return Type Void
forall a. Type a
Int64T
lub Type Void
Float32T Type Void
Float32T = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return Type Void
forall a. Type a
Float32T
lub Type Void
Float64T Type Void
Float64T = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return Type Void
forall a. Type a
Float64T
lub Type Void
BoolT Type Void
BoolT = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return Type Void
forall a. Type a
BoolT
lub Type Void
TextT Type Void
TextT = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return Type Void
forall a. Type a
TextT
lub Type Void
NullT Type Void
NullT = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return Type Void
forall a. Type a
NullT
lub Type Void
BlobT Type Void
BlobT = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return Type Void
forall a. Type a
BlobT
lub Type Void
PrincipalT Type Void
PrincipalT = Type Void -> Either String (Type Void)
forall (m :: * -> *) a. Monad m => a -> m a
return Type Void
forall a. Type a
PrincipalT

-- The shorthands
lub Type Void
BlobT t :: Type Void
t@(VecT Type Void
_) = Type Void -> Type Void -> Either String (Type Void)
lub (Type Void -> Type Void
forall a. Type a -> Type a
VecT Type Void
forall a. Type a
Nat8T) Type Void
t
lub t :: Type Void
t@(VecT Type Void
_) Type Void
BlobT = Type Void -> Type Void -> Either String (Type Void)
lub (Type Void -> Type Void
forall a. Type a -> Type a
VecT Type Void
forall a. Type a
Nat8T) Type Void
t

-- failure
lub Type Void
t1 Type Void
t2 = String -> Either String (Type Void)
forall a b. a -> Either a b
Left (String -> Either String (Type Void))
-> String -> Either String (Type Void)
forall a b. (a -> b) -> a -> b
$ Doc Any -> String
forall a. Show a => a -> String
show (Doc Any -> String) -> Doc Any -> String
forall a b. (a -> b) -> a -> b
$ Doc Any
"Incompatible types: " Doc Any -> Doc Any -> Doc Any
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Type Void -> Doc Any
forall a ann. Pretty a => a -> Doc ann
pretty Type Void
t1 Doc Any -> Doc Any -> Doc Any
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Doc Any
" and " Doc Any -> Doc Any -> Doc Any
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Type Void -> Doc Any
forall a ann. Pretty a => a -> Doc ann
pretty Type Void
t2