Недавно я наткнулся на 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, но я понятия не имею, как сделать что более конкретна, чем его текущая рука-волновая форма или эта интуиция верна.