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