Недавно я наткнулся на Djinn и кратко играл с ним, чтобы попытаться выяснить, будет ли это полезно в моем повседневном рабочем процессе кодирования. Я был рад видеть, что у Джинна были монады, и он попытался понять, сможет ли он найти какие-нибудь классные функции.
Джинн действительно натворил чудеса. Типичная подпись изначально (по крайней мере для меня) неинтуитивной функции >>= (>>=)
равна Monad m => ((a -> m b) -> m a) -> (a -> m b) -> m b
. Джинн смог немедленно демистифицировать это, указав
Djinn> f ? Monad m => ((a -> m b) -> m a) -> (a -> m b) -> m b
f :: (Monad m) => ((a -> m b) -> m a) -> (a -> m b) -> m b
f a b = a b >>= b
К сожалению, Djinn, похоже, не может найти другие стандартные функции на монадах, несмотря на то, что знает о стандартном классе Monad.
-
join
(который должен бытьjoin = (>>= id)
или в Djinn более подробный синтаксисjoin a = a >>= (\x -> x)
)Djinn> join ? Monad m => m (m a) -> m a -- join cannot be realized.
-
liftM
(который должен бытьliftM f = (>>= (return . f))
или в Djinn более подробный синтаксисliftM a b = b >>= (\x -> return (a x))
)Djinn> liftM ? Monad m => (a -> b) -> m a -> m b -- liftM cannot be realized.
-
Даже базовый
return :: Monad m => m a -> m (m a)
не может быть найден Djinn илиreturn :: Monad m => (a, b) -> m (a, b)
.Djinn> f ? Monad m => (a, b) -> m (a, b) -- f cannot be realized.
Джинн знает, как использовать \
для построения анонимных функций, так почему это так?
Мое грубое подозрение состоит в том, что, возможно, у Джинна есть упрощенное понятие typeclass и как-то рассматривает m a
как "фиксированный", так что m (a, b)
не рассматривается как случай m a
, но я понятия не имею, как сделать что более конкретна, чем его текущая рука-волновая форма или эта интуиция верна.