Понимание типов в потоковой библиотеке - PullRequest
0 голосов
/ 15 мая 2018

В отношении streaming библиотеки Что такое m в Stream (Of a) m r?Как я могу понять это из документации (извините, нуб здесь) ?

Я хотел бы понять, что означает тип, чтобы я мог решить мою конкретную проблему, где яЯ создаю поток запросов с использованием серванта, и при попытке использовать его следующим образом:

post :: Maybe Int -> ClientM [BlogPost]
post = ...

stream :: Stream (Of (ClientM [BlogPost])) ClientM ()
stream = S.map posts $ S.each $ [Just p | p <- [1..5]]

main = do
  let url = ...
  S.print $ S.map (\x -> runClientM x url) stream

Но я получаю следующую ошибку:

• Couldn't match type ‘ClientM’ with ‘IO’
  Expected type: S.Stream (S.Of (ClientM [BlogPost])) IO ()
    Actual type: S.Stream (S.Of (ClientM [BlogPost])) ClientM ()

1 Ответ

0 голосов
/ 15 мая 2018

Если задано отдельно, m в Stream (Of a) m r может быть любого типа.

При рассмотрении конкретных функций в модуле учитывайте ограничение типа.Например, функция yield имеет такой тип:

yield :: Monad m => a -> Stream (Of a) m ()

Здесь m ограничен любым типом, который является экземпляром Monad.Это может быть IO, [] (список), Maybe, State, Reader и т. Д.

Другая функция имеет такой тип:

stdinLn :: MonadIO m => Stream (Of String) m ()

Здесьm должен быть любым типом, который является экземпляром MonadIO.Класс типа MonadIO является подклассом Monad, в том смысле, что для типа, равным MonadIO, он уже должен быть Monad.

AFAICT, IO такжеMonadIO, но, например, Maybe нет.

Таким образом, некоторые функции в модуле более ограничены, чем другие.Функция yield менее ограничена, чем функция stdinLn.Вы можете использовать Maybe как m с yield, но не с stdinLn.

Что касается вашей конкретной проблемы, в OP недостаточно информации для воспроизведения, но похоже, что main использует функцию map из Streaming.Prelude:

map :: Monad m => (a -> b) -> Stream (Of a) m r -> Stream (Of b) m r

Здесь m должен быть Monad экземпляром.В Haskell функция main должна иметь тип IO (), поэтому при использовании нотации do экземпляр Monad выводится как IO.Сообщение об ошибке гласит, что компилятор ожидает, что m будет IO.

...