Рассмотрим следующий пример:ограничение Мономорфизм срабатывает, когда общий экземпляр определяется
{-# 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.
Вы правы, это может быть такая же ошибка. Вероятно, стоит проверить, исправлено ли это в разделе HEAD/7.10.2. Проблема заключается в том, что добавленный экземпляр предоставляет GHC два способа уменьшить ограничение 'T t (F r)', возникающее из-за использования 'fromScalar'', и по какой-то причине GHC решает применить экземпляр, а не словарь, предоставляемый 'convert'. – kosmikus
Если это правда, моя удача ужасная ... Мне удалось найти ту же ошибку снова в совершенно другой обстановке! – crockeea
Получается, что эта ошибка отличается от [# 10195] (https://ghc.haskell.org/trac/ghc/ticket/10195). Вы можете прочитать больше [здесь] (https://ghc.haskell.org/trac/ghc/ticket/10338). – crockeea