2015-07-06 2 views
4

Следующий тест взял меня врасплохHaskell - пусть связывание выбирает неверный экземпляр

{-# LANGUAGE FlexibleInstances #-} 
{-# LANGUAGE UndecidableInstances #-} 
module Test where 

class Type t where 
    encodeToField :: t -> String 

class Rec r where 
    encodeToRec :: r -> String 

data X a b = X a b 

instance (Type t) => Rec t where 
    encodeToRec = encodeToField 

instance (Type t, Rec r) => Rec (X t r) where 
    encodeToRec (X t r) = 
     let x = encodeToField t 
      y = encodeToRec r 
     in x ++ y 

GHC терпит неудачу на этом с

Test.hs:19:17 
Could not deduce (Type r) arising from a use of `encodeToRec' 
from the context (Type t, Rec r) 

По какой-то причине GHC хочет использовать экземпляр Type t => Rec t в y = encodeToRec r, вместо просто беря Rec r из контекста объявления экземпляра.

Если избежать Выпускаемое связывания и вместо того, чтобы писать

instance (Type t, Rec r) => Rec (X t r) where 
    encodeToRec (X t r) = encodeToRec t ++ encodeToRec r 

компилирует.

Является ли это ошибкой в ​​ghc или должно ли это поведение ожидаться из-за используемых языковых расширений?

+0

Пока не понял этого, но я обнаружил, что более простая программа создает проблему: если вы определяете 'newtype Foo a = Foo a', тогда определите экземпляр' Rec r => Rec (Foo r) ', с' encodeToRec (Foo r) = x, где x = encodeToRec r', он дает ту же ошибку. Хотя экземпляр вообще не относится к типу. Странно ... –

+0

@ AdamR.Nelson Спасибо за упрощение. Мне не хотелось работать, надеюсь, что OP не слишком длинный :-) –

+0

Это кажется странным. Выражение '++' не должно быть typecheck, так как 't' не имеет ограничения' Rec'? – Sibi

ответ

1

Этот запах очень похож на known bug: ваш код компилируется, когда я удаляю общий экземпляр, но GHC не находит установленное ограничение в его присутствии. У меня есть соответствующий вопрос SO here. Если это одна и та же ошибка, она может быть не исправлена ​​какое-то время (если вообще).

+0

Вы уверены, что оба ошибки одинаковы? Пример, указанный в связанном билете, включает семейство типов. Возможно, файл другой вопрос ghc, чтобы получить подтверждение? Будете ли вы это делать или я могу подать вопрос? (Нет никакого вреда в запросе ghc-devs, если это ошибка, даже если она дублируется связанной ошибкой.) – Sibi

+0

Я не эксперт GHC, поэтому я не могу быть уверен, что это то же самое. Отправляйся, если хочешь ... – crockeea

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