Hi guys, I'm trying to read/write a socket without having to close the handle. However, it seems like whatever I do, I cannot read the socket contents until the handle is closed.
Client code:import Network.Socket import Network.BSD import Control.Monad import System.IO as IO import Data.Text as T import Data.ByteString.Lazy as BSL import Data.MessagePack as MP main = withSocketsDo $ do sock <- socket AF_INET Stream 0 setSocketOption sock ReuseAddr 1 addr <- liftM hostAddresses $ getHostByName "localhost" connect sock $ SockAddrInet (fromInteger 8585) (Prelude.head addr) handle <- socketToHandle sock ReadWriteMode hSetBuffering handle NoBuffering replicateM_ 5 $ BSL.hPut handle $ MP.pack ("Hello host" :: Text) hFlush handle getLine replicateM_ 5 $ BSL.hPut handle $ MP.pack ("Hello host" :: Text) hFlush handle hClose handle
Server code:import Network.Socket import Network.Socket.ByteString as NSB import Network.Socket.ByteString.Lazy as NSBL import Data.MessagePack as MP import Data.Text as T import Data.ByteString.Lazy as BSL import Data.ByteString as BS import Data.HashMap as HM import System.IO as IO runServer :: Integer -> IO () runServer port = withSocketsDo $ do sock <- socket AF_INET Stream 0 setSocketOption sock ReuseAddr 1 bindSocket sock (SockAddrInet (fromInteger port) iNADDR_ANY) listen sock 100 servLoop sock servLoop :: Socket -> IO () servLoop sock = do connection <- accept sock onConnect connection servLoop sock onConnect :: (Socket, SockAddr) -> IO () onConnect (client, client_addr) = do IO.putStrLn "Got a connection" h <- socketToHandle client ReadWriteMode hSetBuffering h NoBuffering req <- BSL.hGet h 1024 IO.putStrLn "Got some contents: " IO.putStrLn $ show req
So the observed behavior is that the linereq <- BSL.hGet h 1024
doesn't evaluate until AFTER the client closes the handle. Is there a reason for that? and can I just have it continually stream data without closing the handle?submitted by fuzzyslippers42
[link] [8 comments]
Can any one tell me how to start learning Haskell? Any series of tutorials i tired but unable to find quality tutorials. That is might be because Haskell is not a popular language like others.submitted by mu_livecodingtv
[link] [5 comments]
Typically, when people explain monads, they begin with (>>=) and how it is used in desugaring the do notation. However, I've always found this very confusing because the data flows in the opposite direction from normal function application. Even LYAH only mentions (>>=).
I believe it is a good way to explain the different kinds of function applications by showing the following progression:
For a normal functionincByOne :: Int -> Int incByOne = (+1)
we apply it to the value twice as eitherincByOne (incByOne 1) > 3
or using ($)incByOne $ incByOne $ 1 > 3
We can apply the function to a value in functor context using (<$>)incByOne <$> incByOne <$> Just 1 > Just 3
EDIT. As rightly pointed out by /u/imz , the above should be written asincByOne <$> (incByOne <$> Just 1)
because (<$>) is left associative. See stack overflow question. Basically, my original example really is (incByOne <$> incByOne) <$> Just 1 and it only worked because -> is a functor.
Finally, we create a monadic versionincByOneM :: Int -> Maybe Int incByOneM n = if (n > 0) then Just $ n + 1 else Nothing
and we can apply it to the value in a monadic contextincByOneM =<< incByOneM =<< Just 1 > Just 3 incByOneM =<< incByOneM =<< Just (-1) > Nothing
Furhermore, we can mix the monadic and the non-monadic version as follows:incByOneM =<< incByOne <$> Just 1 > Just 3 incByOne <$> (incByOneM =<< Just 1) > Just 3
Only after that explanation, I believe it is instructive to introduce (>>=) by saying that it inverses the dataflow (from left to right) as follows:Just 1 >>= incByOneM >>= incByOneM > Just 3
Comments? Do you find it useful? Any existing resources using this style of explanation?
EDIT2: It seems the conclusion from the discussion is that supporting dataflow from left-to-right and right-to-left equally well is needed. To make all examples from this question equally well expressible using the left-to-right way, we can use the & operator:incByOne $ incByOne $ 1 1 & incByOne & incByOne
However, there's no standard operator for values in the functor context. Probably a good analogue could be <&>:incByOne <$> (incByOne <$> Just 1) (Just 1 <&> incByOne) <&> incByOne
EDIT5: /u/Peaker pointed out that &, <&>, and >>= are all left associative, so no parentheses needed forJust 1 <&> incByOne <&> incByOne
And, for values in monadic context we haveincByOneM =<< incByOneM =<< Just 1 Just 1 >>= incByOneM >>= incByOneM
So, the question is: has anybody considered adding something like <&> to base?
EDIT4: both (&) and (<&>) are defined in Control.Lens.Operators but it would be really great to have them both in base.EDIT5: CONCLUSION.
Thanks everybody for your insights. I've learned quite a lot here. Here's my summary after applying both styles (left-to-right and right-to-left) in my code.Using $, <$>, and =<< + applicative
This was my style. These operators shine in two cases:
[+] with datatype constructors (and applicative style)Person <$> getFirstName <*> getLastName
because it keeps the same shape as the datatype:data Person = Person String String
[+] point free stylelet f = incByOne $ incByOne
instead oflet f n = incByOne $ incByOne n
However, problems arise due to mixed infixity, since <$> is left associative whereas $ and =<< are right associative.
[-] requires careful placement of bracketsincByOne <$> (incByOne <$> Just 1) Using &, <&>, and >>=
These really shine in two cases:
[+] creating a pipe through which data flows left-to-right (which follows the direction of -> in type definition)1 & Just <&> incByOne >>= incByOneM
no brackets needed here since all of them are left-associative and have the same infixity (1).
[+] applying multiple modifications to the same object. This is particularly nice with lenses:Person "Alic" "Bck" & name .~ "Alice" & lastName .~ "Black"
[-] have to import Control.Lens ((&), (<&>))
[-] cannot use them point-free stylesubmitted by mallai
[link] [49 comments]
ajnsit on Github has made a lot of progress towards getting ghc-mod work with stack.
I had a few bugs (package-db paths had trailing newlines) which I fixed in my version of the repo.
I just got ghc-mod working on my desktop by following the following steps:git clone https://www.github.com/parsonsmatt/ghc-mod cd ghc-mod && git checkout stack-support stack install
I'm now able to do type inspection with vim on all my stack projects :D
I'd appreciate if others could give it a shot and report their experiences, either here or on Github.submitted by ephrion
[link] [10 comments]
[link] [12 comments]
Is it a monad, in the sense that it binds all the money and returns ()? I am Greek so feel free to write anything you like...submitted by nikosquant