В "Типы данных a la carte" Swierstra пишет, что с учетом Free
(который он называет Term
) и Zero
вы можете реализовать монаду Identity:
data Term f a = Pure a
| Impure (f (Term f a))
data Zero a
Term Zero
теперь является монадой Identity. Я понимаю, почему это так. Проблема в том, что я никогда не могу использовать Term Zero
как Monad из-за жесткого ограничения Functor f =>
:
instance Functor f => Monad (Term f) where
return x = Pure x
(Pure x) >>= f = f x
(Impure f) >>= t = Impure (fmap (>>=f) t)
Как сделать Zero
functor?
instance Functor Zero where
fmap f z = ???
Кажется, здесь есть трюк: Поскольку Zero
не имеет конструкторов, Impure
никогда не может использоваться, поэтому случай Impure
>>=
никогда не вызывается. Это означает, что fmap
никогда не вызывается, поэтому есть смысл, в котором это нормально:
instance Functor Zero where
fmap f z = undefined
Проблема в том, что это похоже на обман. Что мне не хватает? Действительно ли Zero
Functor? Или, может быть, Zero
не является Функтором, и это является недостатком того, как мы выражаем Free
в Haskell?