import Data.List.Split
import Control.Applicative
getncheck_guesslist :: IO [Int]
getncheck_guesslist = map read . splitOneOf ",;" <$> getLine
Каждый раз, когда код сводится к foo >>= return . bar
, что вы делаете, отлаживая do-блок (и исправляя ошибку типа), вы не используете монадические функции своей монады, а только ее функторную часть, то есть прямо скажем, вы не возитесь с IO
частью шрифта, а с a
из IO a
:
(<$>) :: (Functor f) => (a -> b) -> f a -> f b
(fmap
будет неинфиксным именем для <$>
. Оба тесно связаны с map
.)
Этот код выше идиоматичен для специального кода, но чистый код будет выглядеть как
import Data.Maybe
maybeRead :: Read a => String -> Maybe a
maybeRead = fmap fst . listToMaybe . reads
-- That fmap is using "instance Functor Maybe"
parseGuessList :: String -> [Int]
parseGuessList = catMaybes . map maybeRead . splitOneOf ",;"
getncheck_guesslist = parseGuessList <$> getLine
или, альтернативно, если вы не хотите игнорировать ввод не-int, но выводить ошибку,
parseGuessList xs = if success then Just . catMaybes $ ys else Nothing
where ys :: String -> [Mabye Int]
ys = map maybeRead . splitOneOf ",;" $ xs
success = all isJust ys
(Осторожно, я только доказал, что код правильный, но на самом деле не пробовал.)
Если это станет более сложным, чем то, что вы захотите использовать правильную библиотеку синтаксического анализа, я думаю.