guard :: (MonadPlus m) => Bool -> m()
guard True = return()
guard False = mzero
Prelude Control.Monad> :t mzero
mzero :: (MonadPlus m) => m a
В Ложному ветви guard
, тип mzero
является m a
, но тип возвращаемого guard
был определен как m()
. Поэтому я не совсем понимаю, почему компилятор не будет жаловаться на это.«м а» против «м()» в гвардии
Я имею в виду, если mzero
возвращает значение, введенное как Maybe Int
, что, конечно, отличается от Maybe()
, правильно?
'mzero' может возвращать что-то вроде 'Maybe Int', правильно? Я думаю, что это отличается от «Maybe()» – aXqd
@aXqd: для монады Maybe, 'mzero = Nothing', которая не имеет предпочтительного типа для' a'. Если вы действительно наложили 'Nothing' на' Maybe Int', оно отличается от 'Maybe()'. Тем не менее, тип 'Maybe a' для любого возможного' a', а не 'Maybe Int', поэтому' Maybe() 'действителен. – kennytm
@KennyTM Спасибо за ваш ответ. Да, я могу использовать плохой пример. Однако, если я напишу собственный тип - «MyType», а затем сделаю его экземпляром «Monad» и «MonadPlus». Я могу сделать mzero 'return' MyType Int '. На самом деле, я думаю, если есть вероятность, что то, что будет возвращено «mzero», не является «m()», компилятор должен жаловаться на это. Поскольку тип «mzero» и тип возврата «guard» не совпадают друг с другом. Я знаю, что я ошибаюсь в этом заключении. Я просто не знаю, где проблема. : P – aXqd