Составление потоковых потоков разных типов - PullRequest
0 голосов
/ 25 мая 2018

Согласно потоковому учебнику , можно комбинировать разные потоки, используя оператор <> ( реэкспортированный из Semigroup на streamly), например так:

runStream $ ((readLn :: IO Int) |: nil) <> ((readLn :: IO Int) |: nil) & S.mapM print

Однако я хотел бы объединить потоки, которые имеют разные типы, но оба работают с print.Примерно так:

runStream $ ((readLn :: IO Int) |: nil) <> ((readLn :: IO [Char]) |: nil) & S.mapM print

Но это дает мне ошибку:

<interactive>:27:45: error:
    • Couldn't match type ‘[Char]’ with ‘Int’
      Expected type: SerialT IO Int
        Actual type: SerialT IO [Char]
    • In the second argument of ‘(<>)’, namely
        ‘((readLn :: IO [Char]) |: nil)’
      In the first argument of ‘(&)’, namely
        ‘((readLn :: IO Int) |: nil) <> ((readLn :: IO [Char]) |: nil)’
      In the second argument of ‘($)’, namely
        ‘((readLn :: IO Int) |: nil) <> ((readLn :: IO [Char]) |: nil)
           & S.mapM print’

Любые подсказки, как это сделать?


Приведенный выше код имеетбыл запущен в ghci с этими импортами:

import Streamly
import Streamly.Prelude ((|:), nil)
import qualified Streamly.Prelude as S
import Data.Function ((&))

1 Ответ

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

Поскольку S.mapM работает только с вещами, которые уже являются монадами, предположительно, вы можете преобразовать их в общий тип - скажем, те, которые содержат String s, - затем пересечь тип общего потока.print это просто putStrLn . show, поэтому:

runStream $ (show <$> ((readLn :: IO Int) |: nil)) <> (show <$> ((readLn :: IO [Char]) |: nil)) & S.mapM putStrLn
...