Самостоятельные ссылки на типы записей в Standard ML - PullRequest
0 голосов
/ 30 ноября 2018

Я хотел бы создать объявление типа записи, такое как

type 'a cx = { foo : string, handler : 'a cx -> 'a cx }

, но этот код не компилируется.

Я также пробовал "взаимно рекурсивные объявления синонимов типов", вроде

type 'a cx = { foo : string, handler : 'a hnd }
and 'a hnd = 'a cx -> 'a cx;

безуспешно.

В Haskell это будет

data Cx a = MkCx { foo :: String, handler :: Cx a -> Cx a }

Как мне добиться этого в SML?

ОБНОВЛЕНИЕ

Это возможно с взаимно рекурсивными типами данных

datatype 'a cx = MkCx of string * ('a hnd)
and 'a hnd = MkHnd of 'a cx -> 'a cx;

, но это уродливо и нет хорошего синтаксиса записи с неупорядоченным доступом.

Ответы [ 3 ]

0 голосов
/ 01 декабря 2018

Ближайшей к вашей попытке будет:

datatype 'a cx = CX of { foo : string, handler : 'a hnd }
withtype 'a hnd = 'a cx -> 'a cx

Однако для доступа к записи требуется сопоставление с образцом.Определение функций доступа может сделать это более удобным.

0 голосов
/ 28 декабря 2018

Создание алгебраического типа данных с одним конструктором работает для меня в SML / NJ без необходимости определять несколько типов:

datatype 'a cx = CX of { foo : string, handler : 'a cx -> 'a cx }

type не работает, потому что он просто определяет псевдоним (например,typedef в C), который не может быть рекурсивным.

0 голосов
/ 30 ноября 2018

В итоге я упаковал отдельные типы в один модуль, т.е.

type 'a cx = { foo : string };
type 'a hnd = 'a cx -> 'a cx
signature CX = sig
    type t
    val cx : t cx
    val handler : t hnd
end
...