Понимание типов в потоковой библиотеке

Что касается библиотеки 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 ()
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
5
0
83
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Если дано отдельно, 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.

Интересное замечание: по соглашению переменная типа с именем m почти всегда представляет монаду (а f - какой-то другой функтор).

luqui 15.05.2018 09:48

Несколько других соглашений: f, g, h для функций, a, b, c для параметров типа, s для потока, заканчиваются на s для списков / массивов / векторов, v для вектора, суффикс T для преобразователя, префикс m для Maybe, e для Exception, префикс e для Either. Вы можете придумать что-нибудь еще?

MCH 15.05.2018 10:28

@MCH Префикс m иногда означает Monoid, как в mappend и mconcat. Точно так же (по крайней мере, до база-4.11.0.0) префикс s также может означать Semigroup, как в sconcat и stimes.

Mark Seemann 15.05.2018 10:47

Другие вопросы по теме