Я написал следующую простую функцию
u f=f.f
В соответствии с ghci это имеет сигнатуру типа
u :: (b -> b) -> b -> b
Однако эта подпись типа слишком строгая. Haskell гарантирует, что наш ввод будет иметь тип (b -> b), когда это не обязательно должно быть. Например, функция (:[]) имеет сигнатуру типа
(:[]) :: a -> [a]
Это не форма (b -> b) (если вы не разрешаете бесконечные типы) и, следовательно, не может быть передана u. Однако вы можете составить (:[]) с собой.
g=(:[]).(:[])
Это работает и имеет тип
(:[]).(:[]) :: a -> [[a]]
Поэтому я должен в принципе передать это u.
Я попытался написать новую подпись типа, чтобы заменить сгенерированную подпись, но я не мог придумать способ выражения требований функции. Я всегда придумываю подпись того же типа, которую предоставляет компилятор. Есть ли сигнатура типа, которую мы можем дать, чтобы ослабить u, чтобы функции, подобные (:[]), могли быть переданы ей?