SafeLink в Слуга - PullRequest
       20

SafeLink в Слуга

4 голосов
/ 27 мая 2019

Servant использует Servant.API.safeLink для генерации относительных URL-адресов, но я сталкиваюсь с проблемой, которая заставляет меня думать, что я неправильно понимаю что-то базовое либо о том, как его использовать, либо о том, как определять API Servant.

Минимальный пример, который я построил, содержит две конечные точки. Один из них предназначен для использования в качестве конечной точки «входной двери» (относительный URL) /foo, а другой - /foo/1:

{-# LANGUAGE DataKinds     #-}
{-# LANGUAGE TypeOperators #-}
import Servant

data HTML
type Foo = "foo" :> (Foo0 :<|> Foo1)
type Foo0 = Get '[HTML] String
type Foo1 = "1" :> Get '[HTML] String

slFoo :: Link
slFoo = safeLink (Proxy :: Proxy Foo) (Proxy :: Proxy Foo1)

Определение slFoo выше дает мне ошибку

Could not deduce: IsElem' ("1" :> Get '[HTML] String) ("foo" :> (Foo0 :<|> Foo1))

... это именно та ошибка, которую я получаю, когда safeLink просят создать ссылку, которой нет в API, определенном его первым параметром. Ошибка аналогична, когда второй параметр safeLink равен Proxy :: Foo0.

Я перепробовал многие, многие варианты этого и, похоже, сам не могу понять это с использованием найденной мной документации. Буду признателен за некоторые советы, которые позволят мне понять, в чем заключаются мои недоразумения.

1 Ответ

0 голосов
/ 13 июня 2019

Пример не работает, потому что Foo1, тип, который вы определили для конечной точки, сам по себе не содержит полного пути относительно вершины Foo API.

Один из способов исправить эту ситуацию - использовать вместо этого «плоский» API:

safeLink (Proxy :: Proxy (Flat Foo)) (Proxy :: Proxy (Nth 1 (Flat Foo)))

(требуется также import Servant.API.Flatten)

Недостатком является то, что вы должны знать порядковый номер Foo1 в пределах Foo. Похоже, не существует способа получить нужный ответ, используя типы, указанные в вашем вопросе. Вы могли бы в первую очередь определить плоский API, за счет того, чтобы сделать структуру понятной (IMO).

Спасибо Alp Mestanogullari за объяснение этого мне выше, в комментариях к вопросу. Он действительно должен получить кредит за ответ!

...