Я реализую typechecker в Haskell. Основная подпись проверки типов функцийMonadic guard с Либо
judge :: Term -> StateT Context (Either String) Type
Если программа проверки не удается, он возвращает lift $ Left "Something went wrong"
.
Например, функция typecheck ПЧ (псевдо):
judge (ExpIf test cons alt) =
do
testT <- judge test
consT <- judge cons
altT <- judge alt
guard $ consT == altT
Первоначально этот код был записан следующим образом.
judge (ExpIf test cons alt) =
do
testT <- judge test
consT <- judge cons
altT <- judge alt
if altT == consT
then return consT
else lift $ Left "Types for cons and alt do not match"
Учитывая, что, если у меня есть несколько охранников, я бы слишком много indendation, поэтому я изменил мой код, чтобы использовать guard
с.
Я знаю, что тип возвращаемого выражения guard
является ()
, но в фоновом режиме, что делает мою Either
монады неудачи, а вернувшись Left ""
. Есть ли способ передать строчку охраннику?
judge (ExpIf test cons alt) =
do
testT <- judge test
consT <- judge cons
altT <- judge alt
guard (consT == altT) "types of cons and alt should match!"
Единственный способ определить более определенную функцию типа 'guardE :: Bool -> String -> EitherT m String()'. 'guard' по существу слишком полиморфен, чтобы принять строковый аргумент - он работает для любой« Альтернативы », которая не делает предположений о возможности« выбросить ошибку из строки ». Вы можете использовать 'Monad {Throw/Catch}' здесь вместо простого 'Either', если вы хотите общности. – user2407038