Поскольку ваш getS
возвращает String
, а не IO String
, нет необходимости "извлекать" чистое значение с помощью <-
.
Просто используйте
do
let line = getS x
putStrLn line
getV xs
Также есть функция mapM
, которую вы можете
getV xs = mapM (putStrLn.getS) xs
и ваш getS
использует монады без необходимости.
getS [] = ""
getS ((c,_):str) = "(L" ++ [c] ++ ")" ++ getS str
Конечно, написать его можно только с помощью встроенных функций.
getS ps = concatMap (\(c,_) -> "(L" ++ [c] ++ ")") ps
Причина, по которой ваш код не приводит к сбою в строке line <- getS x
и line
становится Char
, заключается в том, что List также является монадой. Например, мы можем написать декартово произведение как
cartesian :: [a] -> [b] -> [(a,b)]
cartesian xs ys = do
x <- xs -- # Now x is of type 'a', representing any element in xs
y <- ys -- # Now y is of type 'b', representing any element in ys
return (x, y) -- # Return the tuple composed of any elements in xs and ys.
На самом деле, понимание списка основано на этом монадическом свойстве списка.
cartesian xs ys = [(x, y) | x <- xs, y <- ys]