Как мы можем избежать - если это имеет смысл сделать ... - использование lift
в MaybeT
?
Классический пример из вики-книг .
Учитывая
isValid :: String -> Bool
isValid s = length s >= 8
&& any isAlpha s
&& any isNumber s
&& any isPunctuation s
У нас есть
getPassphrase :: MaybeT IO String
getPassphrase = do s <- lift getLine
guard (isValid s) -- Alternative provides guard.
return s
askPassphrase :: MaybeT IO ()
askPassphrase = do lift $ putStrLn "Insert your new passphrase:"
value <- getPassphrase
lift $ putStrLn "Storing in database..."
То, что я пробовал
Я думаю, мне нужно использовать ask
и tell
, поэтому я Код был преобразован следующим образом:
getPassphrase :: MaybeT (ReaderT String IO) String
getPassphrase = do
s <- ask
guard (isValid s) -- Alternative provides guard.
return s
askPassphrase :: MaybeT (ReaderT String IO) ()
askPassphrase = do
-- _ <- tell "Insert your new passphrase:"
value <- getPassphrase
-- _ <- tell "Storing in database..."
return ()
main :: IO (Maybe ())
main =
runReaderT (runMaybeT askPassphrase) "test123!"
Строка "test123!"
создает Just()
, а "test123"
возвращает Nothing
, поэтому IMO работает должным образом, но я все еще имею включить Writer.
Если я делаю
askPassphrase :: MaybeT (ReaderT String (WriterT String IO)) ()
askPassphrase = do
_ <- tell "Insert your new passphrase:"
let value = getPassphrase
_ <- tell "Storing in database..."
return ()
main :: IO ()
main =
execWriterT (runReaderT (runMaybeT askPassphrase) "test123!") >>= putStrLn
, он компилируется и запускается, но что-то идет не так, потому что любая строка считается допустимой, я имею в виду, что я всегда вижу "Insert your new passphrase:Storing in database..."
на выходе. Чего мне не хватает?