Я начал свое первое простое веб-приложение в Elm. Большая часть моего кода в настоящее время адаптирована из https://github.com/rtfeldman/elm-spa-example. Я работаю против API, который даст мне authToken в заголовке ответа. У меня есть тип AuthToken, который должен представлять этот токен. Извлечение значения из заголовка и преобразование его в результат, который вызывает ошибку либо String
, либо AuthToken
. Я ожидал, что могу просто сказать, что возвращаю AuthToken, возвращаю String, и это было бы хорошо, потому что сейчас мои AuthToken - это просто строки. Похоже, что в типах Вязов есть что-то, чего я не понимаю.
Вот определение AuthToken
:
type AuthToken
= AuthToken String
и моя слишком сложная функция, которая сейчас просто пытается внести некоторые изменения типа (позже я хочу также поработать здесь над телом):
authTokenFromHeader : String -> Http.Response String -> Result String AuthToken
authTokenFromHeader name resp =
let
header = extractHeader name resp
in
case header of
Ok header ->
let
token : Result String AuthToken
token = Ok (AuthToken header)
in
token
Err error -> Err error
Я ожидал, что счастливый случай вернет результат Ok со строкой из заголовка ответа, преобразованной в AuthToken
в качестве ее значения. Вместо этого я получаю Cannot find variable 'AuthToken'
. Из документации я ожидал получить конструктор с тем же именем, что и тип. Если я просто использую Ok header
, компилятор будет недоволен, потому что я возвращаю Result String String
вместо обещанного Result String AuthToken
.
Какой здесь правильный подход?
@IgorDrozdov прав, вы должны предоставить конструктор типа в модуле, в котором вы определяете AuthToken module X.AuthToken exposing (AuthToken(..))
, а также в котором вы импортируете модуль import X.AuthToken exposing (AuthToken(..))
. Боковое замечание: что также сбивает с толку (хотя и не неверно), так это то, что вы определяете header
дважды (один раз как результат в привязке let и один раз как строку в вашем шаблоне case)
Код выглядит нормально как есть. Сообщение об ошибке указывает, что type AuthToken
был определен в другом модуле и не импортирован полностью в модуль, который определяет authTokenFromHeader
. Вы можете прочитать о модульной системе Elm в руководстве Elm: Модули.
Возможное исправление, предполагающее, что type AuthToken
определено в модуле Types
, а authTokenFromHeader
определено в модуле Net
, следующее:
Types.elm:
module Types exposing (AuthToken(..))
type AuthToken = AuthToken String
Net.elm:
module Net exposing (authTokenFromHeader)
import Types exposing (AuthToken(..))
authTokenFromHeader : String -> Http.Response String -> Result String AuthToken
authTokenFromHeader name resp =
...
Обратите внимание на использование AuthToken(..)
вместо AuthToken
, что гарантирует, что тип, а также конструкторы типов импортируются / экспортируются.
Или просто переместите определение type AuthToken
в тот же файл, что и определение authTokenFromHeader
.
Спасибо! Я импортировал и выставлял их, но у меня не было (..)
. Каждый раз, когда я видел их, я предполагал, что они указывают на то, что пример был сокращен, пока я не заметил, насколько последовательно вы, @dvekeman и документы использовали их.
Хороший! Я немного обновил ответ, чтобы объяснить важность (..)
.
просто чтобы быть уверенным, что
AuthToken
виден, есть ли у вас определениеtype AuthToken
в том же файле или оно выставлено из какого-то импортированного модуля?