2015-04-21 2 views
5

Рассмотрим следующий пример:ограничение Мономорфизм срабатывает, когда общий экземпляр определяется

{-# LANGUAGE TypeFamilies, FlexibleContexts, GADTs, MultiParamTypeClasses #-} 

type family F r 

class (Functor t) => T t r where 
    fromScalar :: r -> t r 

data Foo t r where 
    Foo :: t (F r) -> Foo t r 
    Scalar :: r -> Foo t r 

toF :: r -> F r 
toF = undefined 

convert :: (T t (F r)) 
    => Foo t r -> Foo t r 
convert (Scalar c) = 
    let fromScalar' = fromScalar 
    in Foo $ fromScalar' $ toF c 

Этот код компилируется с GHC 7.8.4.

Когда я добавить общий экземпляр для T (который требует FlexibleInstances):

instance (Functor t, Num r) => T t r 

GHC жалуется:

Could not deduce (Num (F r)) arising from a use of ‘fromScalar’ 
    from the context (T t (F r)) 
     bound by the type signature for 
       convert :: (T t (F r)) => Foo t r -> Foo t r 
     at Main.hs:(17,12)-(18,23) 
    In the expression: fromScalar 
    In an equation for ‘fromScalar'’: fromScalar' = fromScalar 
    In the expression: 
     let fromScalar' = fromScalar in Foo $ fromScalar' $ toF c 

this question Я вспомнил, но там, кажется, некоторые ключевые различия. Во-первых, самое главное, GHC не жаловался на предварительную инстанцию. Во-вторых, у меня нет RankNTypes, который, похоже, лежит в основе проблемы с этим вопросом. Наконец, добавление NoMonoLocalBinds не помогает. Странно, добавив NoMonomorphismRestrictionделает Извините, но вам необходимо войти в систему или зарегистрироваться. fromScalar to the same message about fromScalar'.

Конечно проблема может быть исправлена ​​путем добавления сигнатуры типа для fromScalar и добавления ScopedTypeVariables:

convert :: forall t r . (T t (F r)) 
    => Foo t r -> Foo t r 
convert (Scalar c) = 
    let fromScalar' = fromScalar :: F r -> t (F r) 
    in Foo $ fromScalar' $ toF c 

Я готов признать, что-то поддатое с мономорфными типами на работе здесь, несмотря на то, снимая ограничения не помогло. Мой вопрос: почему ограничение, вызванное добавлением общего экземпляра? Что еще более важно, почему GHC пытается сопоставить общий экземпляр вместо использования ограничения T (F r)? Это кажется неправильным, и запахи this bug.

+2

Вы правы, это может быть такая же ошибка. Вероятно, стоит проверить, исправлено ли это в разделе HEAD/7.10.2. Проблема заключается в том, что добавленный экземпляр предоставляет GHC два способа уменьшить ограничение 'T t (F r)', возникающее из-за использования 'fromScalar'', и по какой-то причине GHC решает применить экземпляр, а не словарь, предоставляемый 'convert'. – kosmikus

+0

Если это правда, моя удача ужасная ... Мне удалось найти ту же ошибку снова в совершенно другой обстановке! – crockeea

+0

Получается, что эта ошибка отличается от [# 10195] (https://ghc.haskell.org/trac/ghc/ticket/10195). Вы можете прочитать больше [здесь] (https://ghc.haskell.org/trac/ghc/ticket/10338). – crockeea

ответ

0

Это ошибка GHC #10338. К сожалению, похоже, что в ближайшее время он не будет разрешен.

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