2016-01-26 3 views
2

Я реализую 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!" 
+2

Единственный способ определить более определенную функцию типа 'guardE :: Bool -> String -> EitherT m String()'. 'guard' по существу слишком полиморфен, чтобы принять строковый аргумент - он работает для любой« Альтернативы », которая не делает предположений о возможности« выбросить ошибку из строки ». Вы можете использовать 'Monad {Throw/Catch}' здесь вместо простого 'Either', если вы хотите общности. – user2407038

ответ

2

Вы можете комбинировать when/unless либо fail или throwError (в зависимости от конкретной реализации вашей монады этих функций класса полиморфного). Например, вы можете написать:

unless (consT == altT) (throwError "types of cons and alt should match") 
+0

Причина, по которой я выбрал «Либо String», состоит в том, что typechecker действительно не «терпит неудачу». Это была проблема с семантикой ошибки. Я хотел, чтобы у maltyped программы также был выход (т. Е. Сообщение об ошибке). Извините, если мне сложно :) –

+0

@ChristopheDeTroyer Я не уверен, что понял ваш комментарий. Его тон предполагает, что он возражает против какой-то части моего ответа (и извиняюсь за это, ха-ха), но я не могу точно определить, какой конфликт вы видите между тем, что вы сказали, и тем, что я написал в своем ответе. Можете ли вы подробнее рассказать о том, что вы считаете неудовлетворительным? –

Смежные вопросы