Как объявить Maybe изменяемого типа в нечистой нативной функции во Фреге?

Инструмент native-gen генерирует собственное объявление для метода showOpenDialog в javafx.stage.FileChooser вот так

data FileChooser = mutable native javafx.stage.FileChooser where
 native showOpenDialog :: FileChooser -> Window -> IO File

Компиляция приводит к сообщению

Non pure native type File must be MutableIO
    File in IO actions.

Теперь настройка

native showOpenDialog :: FileChooser -> Window -> MutableIO File

приводит к

FileChooser.showOpenDialog has an illegal
    return type for a method that is not pure, perhaps ST s (MutableIO
    File) would work

но следование совету снова приводит к первому сообщению об ошибке.

Компилятор принимает IOMutable File в качестве возвращаемого типа, что имеет смысл, поскольку это действие ввода-вывода, которое возвращает изменяемый тип.

Если возможно, сообщение об ошибке компилятора должно быть адаптировано, чтобы избежать разочарования со стороны пользователя.

Однако в этой особой ситуации файл может быть пустым, поэтому тип ядра будет не File, а Maybe File. Но тогда просто использование IOMutable (Maybe File) приводит к довольно неожиданному сообщению

The type MutableIO (Maybe File) is illegal,
    Maybe File must be a native type.

Любые советы о том, как правильно объявить этот тип?


person Dierk    schedule 19.08.2015    source источник
comment
Обратите внимание, что в исходном сообщении было указано правильное решение: замените File на MutableIO File. К сожалению, разрыв строки оказывается в неудачном положении. Во всяком случае, в сообщении не говорилось удалить IO!   -  person Ingo    schedule 20.08.2015
comment
Правда, хотя я даже не рассматривал это как возможный смысл сообщения :-) В любом случае, будущие читатели этого поста извлекут пользу.   -  person Dierk    schedule 21.08.2015


Ответы (1)


Код, сгенерированный native-gen, неверен, поскольку File был объявлен как IO в native-gen, но File на самом деле определяется как собственный тип с сохранением состояния (не IO), как видно из здесь.

IOMutable определяется как type IOMutable d = IO (MutableIO d). В вашем случае изменяемый собственный тип (MutableIO d) может быть нулевым, поэтому должно работать следующее:

data FileChooser = mutable native javafx.stage.FileChooser where
  native showOpenDialog :: FileChooser -> Window -> IO (Maybe (MutableIO File))
person Marimuthu Madasamy    schedule 19.08.2015
comment
Возможно, следует изменить тип файла. По меньшей мере спорно, оправдывают ли несколько чистых функций то, что это всего лишь ST. - person Ingo; 23.08.2015