-- push based operator, doesn't do what I hoped runEffect (stdin >>~ (\_ -> countLetters))
I understand that the problem is that although the manufacturer starts first, as expected, the first produced value is discarded. Compare ...
GHCi> runEffect (stdin >-> countLetters) countLetters stdin foo 3 countLetters stdin glub 4 countLetters stdin
... from:
GHCi> runEffect (stdin >>~ (\_ -> countLetters)) stdin foo countLetters stdin glub 4 countLetters stdin
This question is discussed in detail by Gabriel Gonzalez in response to this question . This boils down to how the argument of the function you give (>>~)
is the "control" input in the stream, so if you are const
, you end up discarding the first input. The solution is to modify countLetters
:
countLettersPush :: String -> Consumer String IO r countLettersPush str = do lift $ putStrLn "countLetters" lift . putStrLn . show . length $ str str' <- await countLettersPush str'
GHCi> runEffect (stdin >>~ countLettersPush) stdin foo countLetters 3 stdin glub countLetters 4 stdin
I also saw in the discussions here that there is no exact analogue >->
, because it is easy to turn any channel around (I assume with reflection?)
I am not entirely sure of my position, but it seems that this is not entirely applicable to the solution above. What can we do now that the stream stream is working correctly, we use reflect
to rotate it back to pulling based on the stream:
-- Preliminary step: switching to '(>~>)'. stdin >>~ countLettersPush (const stdin >~> countLettersPush) () -- Applying 'reflect', as the documentation suggests. reflect . (const stdin >~> countLettersPush) reflect . const stdin <+< reflect . countLettersPush const (reflect stdin) <+< reflect . countLettersPush -- Rewriting in terms of '(+>>)'. (reflect . countLettersPush >+> const (reflect stdin)) () reflect . countLettersPush +>> reflect stdin
It really depends on the stream, as the stream is controlled by reflect stdin
, below Client
:
GHCi> :t reflect stdin reflect stdin :: Proxy String () () X IO r GHCi> :t reflect stdin :: Client String () IO r reflect stdin :: Client String () IO r :: Client String () IO r
However, the stream involves sending the String
upstream, and therefore it cannot be expressed in terms of (>->)
, that is, so to speak, only with the flow:
GHCi> -- Compare the type of the second argument with that of 'reflect stdin' GHCi> :t (>->) (>->) :: Monad m => Proxy a' a () bmr -> Proxy () bc' cmr -> Proxy a' ac' cm