По существу, ограничение типа Show a
ограничивает переменную типа a
для представления отображаемого типа. Вы, кажется, понимаете это.
Ограничение вида C a b
ограничивает пару переменных типа a
и b
. Интуитивно, это ограничение означает, что между такими типами существует связь.
Рассмотрим этот вымышленный класс
class C a b where
sum :: a -> b -> (Int, b)
Интуитивно понятно, что ограничение C a b
означает, что a
и b
могут быть sum
med вместе (в таком порядке!), И результатом этой суммы будет пара (Int, b)
.
В вашем случае вы имеете дело с
class Monad m => MonadError e m | m -> e where
throwError :: e -> m a
Здесь MonadError e m
выражает следующее соотношение между e
и m
.
m
- это монада
e
- это тип, для которого мы можем преобразовать любое значение x :: e
в throwError x :: m a
для любого a
. Интуитивно понятно, что это тип «ошибка», представляющий природу некоторой ошибки, и throwError
просто включает такое значение внутри монады
- учитывая
m
, есть только один тип ошибки e
. Другими словами, отношение на самом деле является функцией. Это выражается через функциональную зависимость ... | m -> e
в вышеприведенном классе.
Простая версия: MonadError m a
означает, что m
является монадой, которая может выражать некоторые "значения ошибок", типа e
.
Например, если у нас есть MonadError M String
в наличии, мы можем написать
foo :: Int -> M Int
foo n | n == 0 = throwError "can't handle zero!"
| otherwise = return (100 `div` n)