используя типы списков с Haskell '-XDataKinds - PullRequest
2 голосов
/ 29 января 2020

Я использовал тип возврата в функции (используя пакет haskell-src-exts):

import Language.Haskell.Exts.Syntax (Exp(..))
import Language.Haskell.Exts.SrcLoc (SrcSpanInfo(..))
:k Exp SrcSpanInfo
Exp SrcSpanInfo :: *

Это тип. Пока все хорошо.

Но теперь я хотел напечатать это лучше:

:set -XDataKinds
> :k 'List
'List :: l -> [Exp l] -> Exp l

Итак, эта штука хочет еще кое-что. Хорошо, я могу это сделать.

> :k 'List SrcSpanInfo 
'List SrcSpanInfo :: [Exp *] -> Exp *

Один шаг. Хорошо.

> :k 'List SrcSpanInfo [Exp SrcSpanInfo]

<interactive>:1:19: error:
    • Expected kind ‘[Exp *]’, but ‘[Exp SrcSpanInfo]’ has kind ‘*’
    • In the second argument of ‘ 'List’, namely ‘[Exp SrcSpanInfo]’
      In the type ‘ 'List SrcSpanInfo [Exp SrcSpanInfo]’

На данный момент, я чувствую себя смущенным. Мне кажется, что то, что я дал, было определенно в значительной степени тем, о чем он просил. Что именно это значит?

Ответы [ 2 ]

4 голосов
/ 29 января 2020

Из комментариев мне вдруг пришло в голову, что вы, вероятно, на самом деле не ищете поднятые типы (т.е. виды), а скорее обычные типы.

Из комментариев (в частности: ".." . требуемый вид * ... ") кажется, что вы просто хотите создать значение типа Exp SrcSpanInfo (и действительно, эти типы на самом деле не предназначены для использования на уровне вида).

Для этого просто примените параметры к конструктору:

> span = noInfoSpan $ mkSrcSpan noLoc noLoc
> :t span
span :: SrcSpanInfo
> list = List span []
> :t list
list :: Exp SrcSpanInfo

Оригинальный ответ

Выражение [Exp SrcSpanInfo] не обозначает « список типов на уровне типов с одним элементом Exp SrcSpanInfo», но скорее обозначает « единственный тип, представляющий собой список элементов типа Exp SrcSpanInfo», аналогичный [Int] или [String].

Компилятор не может отличить первое от второго, поэтому он по умолчанию использует более старую, более стандартную интерпретацию.

Для того, чтобы сделать это посмотрите список уровня типа, он должен быть заключен в одинарную кавычку, как вы это делали с 'List.

Кроме того, Exp - это тип, но при использовании в виде подписи он повышается до вида. Чтобы создать тип вида Exp *, вы должны использовать один из его конструкторов . Я буду использовать конструктор List, потому что его было проще всего создать:

> :k 'List SrcSpanInfo '[ 'List SrcSpanInfo '[] ]
3 голосов
/ 29 января 2020

[a] - это тип списков. Чтобы создать (продвинутый) список, напишите '[a]:

:k 'List SrcSpanInfo '[ 'List Int '[] ]

Применение 'List к типу, например SrcSpanInfo, вероятно, не то, что вам нужно (надеюсь, мой пример применяет его также Int говорит, что что-то выключено).

...