Haskell - fmap fmap не работает
Вопрос
Я использую GHCi (версия 6.12.3), чтобы немного поиграть с Haskell.Я недавно прочитал о функторах и аппликативных функторах, подумал, нельзя ли реализовать что-то похожее на <*>
аппликативных функторов только с использованием примитивов функторов.Поразмыслив, я придумал сгенерированный код кода, который имел бы (почти) идеальный тип
fmap fmap
или в более общем смысле
Functor f => f (a -> b) -> f (f a -> f b)
Я пробовал
родовое словоУ меня следующая ошибка
родовое слово Написание указанной выше сигнатуры типа, как предлагалось, не помогло.
Самое безумное, когда я набирал (Functor f1, Functor f2) => f1 (a -> b) -> f1 (f2 a -> f2 b)
, я получил эквивалентный тип, как указано выше.
Что я делаю не так?Почему :t fmap fmap
выдает ошибку типа, хотя GHCi находит для нее тип?
Решение
Похоже, вы столкнулись с ограничением мономорфизма .
Попытка вашего примера в GHCi с помощью -XNoMonomorphismRestriction
дает ожидаемый результат.
Вы также можете изменить это, написав код let f x = fmap fmap $ x
.Ограничение мономорфизма применяется только к определениям верхнего уровня, которые «выглядят как» значения, например, f = something
, поэтому введение явного аргумента приводит к тому, что он больше не применяется.Это также не применялось бы, если бы это было не на верхнем уровне (например, в предложении where
).Подробнее см. По ссылке.
Другие советы
Я пока не могу комментировать везде, поэтому опубликую ответ.Как упоминалось ранее, ошибка, которую вы получаете, связана с ограничением мономорфизма.Исправление сигнатуры типа для любого из двух, указанных в исходном вопросе, действительно делает ghci счастливым, как вы и надеялись, может быть, вы просто ошиблись в синтаксисе?
родовое слово