为什么Djinn没有实现共同的monadic功能?

时间:2015-01-25 07:14:46

标签: haskell types

我最近偶然发现了Djinn并且正在简单地玩弄它,试着看看它在我的日常编码工作流程中是否有用。我很高兴看到Djinn有monad,并试图看看它是否能够找到一些很酷的功能。

事实上,Djinn确实有些奇迹。最初(至少对我)非直观函数>>= (>>=)的类型签名是Monad m => ((a -> m b) -> m a) -> (a -> m b) -> m b。 Djinn能够立即通过陈述来揭开神秘面纱的神秘色彩
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上找到其他标准函数,尽管他们知道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.
    
  • Djinn或return :: Monad m => m a -> m (m a)无法找到基本的return :: Monad m => (a, b) -> m (a, b)

    Djinn> f ? Monad m => (a, b) -> m (a, b)
    -- f cannot be realized.
    

Djinn知道如何使用\构建匿名函数,为什么会这样呢?

我粗略怀疑,也许Djinn有一个简单的类型类概念,并以某种方式将m a视为"固定"所以m (a, b)不被视为m a的情况,但我不知道如何使其更具体,而不是当前的手工波浪形式或者直觉是否正确。

1 个答案:

答案 0 :(得分:10)

正确支持类型类似于支持rank-2类型;比较:

join :: Monad m
     => m (m a) -> m a

VS

join :: (forall a. a -> m a)
     -> (forall a b. m a -> (a -> m b) -> m b)
     -> m (m a) -> m a

不幸的是,Djinn使用的技术根本不处理rank-2类型。如果你漂浮起来让Djinn可以处理它,那么你突然得到的是具体的选择:

join :: (b -> m b)
     -> (m c -> (c -> m d) -> m d)
     -> m (m a) -> m a

看起来很像你可以实现它!如果你告诉Djinn使用哪种实例,当然它会好很多。

join :: (b -> m b)
     -> (m (m a) -> (m a -> m a) -> m a)
     -> m (m a) -> m a

对于这个,Djinn将给出正确的实施。 ......但是,这是作弊。