Вопрос

Я использую 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 счастливым, как вы и надеялись, может быть, вы просто ошиблись в синтаксисе?

родовое слово
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top