Скажем, я хочу проанализировать переменную окружения и по умолчанию использовать localhost при ее отсутствии, используя https://hackage.haskell.org/package/network-2.3/docs/Network-URI.html
. Я могу написать такую функцию:
parseRabbitURI :: Text -> Maybe URI.URI
parseRabbitURI "" = URI.parseURI "amqp://guest:guest@127.0.0.1/"
parseRabbitURI uri = (URI.parseURI . toS) uri
Это работает нормально,Теперь скажем, я хочу обрабатывать ошибки.Я отмечаю, что parseURI возвращает Maybe
, так что якобы мне просто нужно сопоставить шаблон с этим.Поэтому я создаю пользовательскую ошибку:
data CustomError = MyCustomError Text deriving(Show)
Я создаю вспомогательную функцию:
parsedExtractor
:: MonadError CustomError.MyCustomError m
=> Text
-> Maybe URI.URI
-> m(URI.URI)
parsedExtractor originalString Nothing = throwError $ FlockErrors.FailedToParseURI originalString
parsedExtractor _ (Just uri) = do
pure uri
Наконец, я изменяю свою начальную функцию:
parseRabbitURI :: MonadError CustomError.MyCustomError m => Text -> m(URI.URI)
parseRabbitURI "" = URI.parseURI "amqp://guest:guest@127.0.0.1/" >>= parsedExtractor "amqp://guest:guest@127.0.0.1/"
parseRabbitURI uri = (URI.parseURI . toS) uri >>= parsedExtractor uri
Это не удаетсяскомпилировать с:
• Couldn't match type ‘URI.URI’ with ‘Maybe URI.URI’
Expected type: URI.URI -> Maybe URI.URI
Actual type: Maybe URI.URI -> Maybe URI.URI
• In the second argument of ‘(>>=)’, namely ‘parsedExtractor uri’
In the expression: (URI.parseURI . toS) uri >>= parsedExtractor uri
In an equation for ‘parseRabbitURI’:
parseRabbitURI uri
= (URI.parseURI . toS) uri >>= parsedExtractor uri
|23 |parseRabbitURI uri = (URI.parseURI. toS) uri >> = parsedExtractor uri |
И по жизни я не могу понять, почему.Если первоначальная реализация возвращает значение Maybe, почему оно конвертируется в URI.URI для развертывания, который я не могу затем передать?
Важно, когда я изменяю шаблон на parsedExtractor
, ожидая строку, это также не компилируется с обратным сообщением (
Couldn't match expected type ‘URI.URI’
with actual type ‘Maybe URI.URI’
Мне кажется, что я упускаю что-то совершенно фундаментальное. Что здесь происходит?