Ошибка компиляции полиморфизма второго ранга в Haskell

Учитывая следующие определения:

import Control.Monad.ST
import Data.STRef

fourty_two = do
  x <- newSTRef (42::Int)
  readSTRef x

Следующие компилируются под GHC:

main = (print. runST) fourty_two -- (1)

Но это не так:

main = (print. runST) $ fourty_two -- (2)

Но тогда, как указывает bdonlan в комментарии, это делает compile:

main = ((print. runST) $) fourty_two -- (3)

Но это не компилируется

main = (($) (print. runST)) fourty_two -- (4)

Что, по-видимому, указывает на то, что (3 )компилируется только из-за специальной обработки инфикса $, однако это все еще не объясняет, почему (1 )компилируется.

Вопросы:

1 )Я прочитал следующие два вопроса(первый , второй), и я пришел к выводу, что $можно только конкретизировать с мономорфными типами. Но я бы также предположил, что .может быть создан только с мономорфными типами, и в результате он также потерпит неудачу. Почему первый код работает, а второй нет? (напр. есть ли специальное правило GHC для первого случая, которое не может применяться во втором?)

2 )Существует ли текущее расширение GHC, которое компилирует второй код? (возможно, ImpredicativePolymorphism сделал это в какой-то момент, но кажется, что это устарело, есть ли что-нибудь вместо этого?)

3 )Есть ли способ определить, скажем, `my_dollar`с помощью расширений GHC, чтобы он делал то, что делает $, но также может обрабатывать полиморфные типы, чтобы (print. runST) `my_dollar` fourty_twoкомпилировался?

Редактировать :Предлагаемый ответ:

Кроме того, следующее не компилируется:

main = ((.) print runST) fourty_two -- (5)

Это то же самое, что и (1 ), за исключением того, что не используется инфиксная версия ..

В результате кажется, что GHC имеет специальные правила как для $, так и для ., но только для их инфиксных версий.

17
задан Community 23 May 2017 в 12:12
поделиться