2015-11-02 2 views
3

Я не понимаю, почему определение demonbind1 дает некоторые ошибки компилятора. это выглядит как глупый флип, но как-то ..РангNpolymorphism и 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

Собственно, это не * довольно * дубликат. В исходном вопросе единственное, что не работало, было «do' notation. Но в настоящее время расширение 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

Это удивительно, и я думаю, в основном это не так. Я помню, как кто-то упоминал о некоторых новых «неповиновенных томах». Ричард Эйзенберг, который недавно внес серьезные изменения в систему типов, ответил, что он не предпринял никаких усилий, чтобы избежать дальнейшего поломки этого уже сломанного расширения. – dfeuer

+0

@dfeuer Я не говорил, что теперь работает «ImpredicativeTypes». Я только сказал, что они * кажутся * * менее сломанными *, и это совершенно другое утверждение. Они, безусловно, не должны использоваться до тех пор, пока они не получат правильное исправление. –

+2

На позитивной ноте, по-видимому, происходит некоторая работа, направленная на то, чтобы заставить их работать: https://ghc.haskell.org/trac/ghc/raw-attachment/wiki/ImpredicativePolymorphism/Impredicative-2015/impredicativity.pdf –

Смежные вопросы