Haskell — Почему это не работает? (Действие ввода-вывода со списками)

#list #haskell #io #return #monads

#Список #haskell #io #Возврат #монады

Вопрос:

 combinationIO :: Int -> [a] -> IO [[a]]
combinationIO 0 _ = return [[]]
combinationIO _ [] = return []
combinationIO n (x:xs) = do res <- (map (x:) (combinationIO (n-1) xs))    (combinationIO n xs)
                          putStrLn $ (show n)    show " : ("    show (x,xs)    show ") = "    show res
                          return res
  

Я видел этот пример (ниже) на каком-то сайте, и мне было интересно, как это работает, поэтому я ввел в него некоторые действия ввода-вывода. Однако ghci выдает мне ошибку типа. В чем проблема?

 combination2 :: Int -> [a] -> [[a]]
combination2 0 _ = [[]]
combination2 _ [] = []
combination2 n (x:xs) = (map (x:) (combination2 (n-1) xs))    (combination2 n xs)
  

Комментарии:

1. В чем ошибка?

2. Если ваш код действительно точно такой, как вы его здесь разместили, то у вас проблема с отступом: putStrLn и return должен иметь отступ точно на уровне, с которого res <- начинается.

Ответ №1:

Основная проблема заключается в том, что map и работать дальше [a] , а не IO [a] . Я думаю, что вы хотели что-то вроде этого:

 combinationIO :: Show a => Int -> [a] -> IO [[a]]
combinationIO 0 _ = return [[]]
combinationIO _ [] = return []
combinationIO n (x:xs) = do
  res1 <- combinationIO (n-1) xs
  res2 <- combinationIO n xs
  let res = (map (x:) res1)    res2
  putStrLn $ (show n)    " : ("    (show (x,xs))    ") = "    (show res)
  return res
  

Комментарии:

1. Или (res1 res2 -> map (x:) res1 res2) <$> combinationIO (n-1) xs <*> combinationIO n xs .