Еще один вопрос новичка, который, вероятно, возник из-за того, что я не понял Monadic do
в Haskell: я хочу написать простой генератор QuickCheck для правильно сформированных URI, используя тип Text.URI
из пакета modern-uri
. Насколько я понимаю, здесь задействованы два типа монад: MonadThrow
для обработки ошибок при построении URI и Gen
из QuickCheck.
Вот моя попытка реализовать генератор. Он не печатает проверку:
import qualified Text.URI as URI
uriGen :: Gen URI.URI
uriGen = do
sc <- elements ["https", "http", "ftps", "ftp"]
tld <- elements [".com", ".org", ".edu"]
hostName <- nonEmptySafeTextGen -- (:: Gen Text), a simple generator for printable text.
uri <- do
scheme <- URI.mkScheme sc
host <- URI.mkHost $ (hostName <> "." <> tld)
return $ URI.URI (Just scheme) (Right (URI.Authority Nothing host Nothing)) Nothing [] Nothing
return uri
Насколько я понимаю, внешний блок do
относится к монаде Gen
, а внутренний обрабатывает MonadThrow
. Я пытаюсь развернуть Text
частей из их Gen
, а затем использовать развернутые Text
для создания URI
частей, развернуть их из их MonadThrow
, затем снова собрать весь URI и, наконец, заключить его в новый Gen
.
Однако я получаю следующую ошибку проверки типа:
• No instance for (MonadThrow Gen)
arising from a use of ‘URI.mkScheme’
• In a stmt of a 'do' block: scheme <- URI.mkScheme sc
In a stmt of a 'do' block:
uri <- do scheme <- URI.mkScheme sc
host <- URI.mkHost $ (hostName <> "." <> tld)
return
$ URI.URI
(Just scheme)
(Right (URI.Authority Nothing host Nothing))
Nothing
[]
Nothing
Судя по ошибке, я подозреваю, что моя интуиция по поводу развертывания и упаковки частей URI неверна. Где я ошибаюсь? Какой должна быть правильная интуиция?
Большое спасибо за вашу помощь!
suchThatMap
и экземплярMonadThrow
дляMaybe
- person moonGoose   schedule 07.05.2020