в ghci код из wiki.haskell.org
newtype Sum n = Sum n
instance Num n => Semigroup (Sum n) where
Sum x <> Sum y = Sum (x + y)
instance Num n => Monoid (Sum n) where
mempty = Sum 0
и у меня репл сначала отругался на n, и сказал мне использовать FlexibleContexts - справедливо, ведь я сказал использовать любое n с ограничением Num .
После этого я попытался применить <> и - неудача: необходимо добавить экземпляр Semigroup (Sum Integer) (я попытался инты сложить обращаясь к свойству полугруппы) :: первый вопрос - почему необходимо добавить экземпляр для Integer, если я при объявлении уже добавил ограничение Num n => ... ?
После этого я попытался сделать этот самый экземпляр, но репл попросил расширение FlexibleInstances. Я его добавил, а после этого добавил и необходимый экземпляр, и всё заработало :: второй вопрос - необходимость во FlexibleInstances была вызвана тем, что я уже добавил прежде общий экземпляр Num n => Semigroup (Sum n)?
Не писали ли вы ещё чего-то в рамках той REPL-сессии? Потому что ваш пример должен работать (и работает) без Flexible… и без экземпляра для Integer.
Хотя… Может, вас попросили добавить Show (Sum Integer)?
FlexibleInstances был нужен, потому что без него декларация должна иметь форму ClassName (TypeConstr a1 a2 … an), а Semigroup (Sum Integer) ей не удовлетворяет: Integer — не переменная типа.
Мне удалось воспроизвести вашу проблему. Хитрость в том, что она работает, только если вы записали newtype Sum n = Sum n, а остальное забыли. Сообщение о неудаче и просьба создать Semigroup (Sum n) появляются из-за отсутствия декларации для Num n => Semigroup (Sum n). Ведь без неё ghci пытается вывести значение it :: (Semigroup (Sum n), Num n) => Sum n, и без FlexibleContexts ему это не удаётся. Далее, с помощью этого расширения он выводит тип it, но не её значение (т.к. указанного ранее инстанса всё ещё нет). Поэтому он и просит создать инстанс для Semigroup (Sum Integer), который, в свою очередь, возможен лишь при включенном FlexibleInstances. Вывод таков: в примере вы забыли записать всё, кроме декларации Sum. Возможно, просто пропустили, а, возможно, вы копировали, но в REPL скопировалась лишь первая строка.
Обсуждают сегодня