2015-11-02 13 views
3

我不明白为什么demonbind1的定义会产生一些编译器错误。它看起来像一个愚蠢的翻转,但不知何故..RankNpolymorphism和kleisli的离谱财富箭头

{-# LANGUAGE GADTs #-} 
{-# LANGUAGE RankNTypes, ScopedTypeVariables, TypeOperators, TypeFamilies,ImpredicativeTypes #-} 

type a :-> b = forall i . a i -> b i 

class IFunctor f where imap :: (a :-> b) -> (f a :-> f b) 

class (IFunctor m) => IMonad m where 
    skip :: a :-> m a 
    bind :: (a :-> m b) -> (m a :-> m b) 


-- Conor McBride's "demonic bind" 
(?>=) :: forall m a b i. (IFunctor m, IMonad m) => m a i -> (a :-> m b) -> m b i 
(?>=) = 
    let 
    -- OK 
    demonbind0 = flip (bind :: forall i. (forall j. a j -> m b j) -> m a i -> m b i) 
    -- KO - see error below 
    demonbind1 = flip bind :: forall i. m a i -> (forall j. a j -> m b j) -> m b i 

    -- So i have to write this 
    demonbind2 :: forall i. (m a i -> (a :-> m b) -> m b i) 
    demonbind2 mai ti = (bind ti) mai 
    in demonbind2 

的错误是

Couldn't match type ‘a j0 -> m b j0’ … 
       with ‘forall i2. a i2 -> m b i2’ 
    Expected type: (a j0 -> m b j0) -> m a i1 -> m b i1 
     Actual type: a :-> m b -> m a i1 -> m b i1 
In the first argument of ‘flip’, namely ‘bind’ 
    In the expression: 
     flip bind :: forall i. m a i -> (forall j. a j -> m b j) -> m b i 
+0

其重复,对不起。 – nicolas

+0

实际上,它不*相当*重复。在原来的问题中,唯一不起作用的是“做”符号。但是现在,GHC的'ImpredicativeTypes'扩展几乎完全不起作用,所以*代码中的所有内容都会中断。即使使用你的'demonbind2'定义,我认为你会很难使用*'(?> =)'。 –

+0

是真的,不是真的重复。我将继续进行手动扩展。这实际上是一个小伤害。现在令人讨厌的是,你会希望*这样简单的操作即可开箱即用。 – nicolas

回答

2

出人意料的是,ImpredicativeTypes似乎比平常的GHC 8.0的开发快照破碎少!这汇编没有错误:

(?>=) :: (IFunctor m, IMonad m) => m a i -> (a :-> m b) -> m b i 
(?>=) = flip bind 

我想知道什么样的改变解决了这个问题。

+1

这是令人惊讶的,而且我认为,大多数情况并非如此。我记得有人提到一些新的“ImpredicativeTypes”破碎。最近对类型系统进行了重大改变的理查德·艾森伯格回应说,他没有做任何努力来避免进一步破坏已经被打破的扩展。 – dfeuer

+0

@dfeuer我没有说'ImpredicativeTypes'现在工作。我只是说他们*看起来*少了*,这是完全不同的说法。他们肯定不应该使用,直到他们得到适当的修复。 –

+2

从积极的方面来看,似乎正在开展一些工作:https://ghc.haskell.org/trac/ghc/raw-attachment/wiki/ImpredicativePolymorphism/Impredicative-2015/impredicativity.pdf –