Haskell websockets标头

时间:2015-03-18 15:41:37

标签: haskell web websocket http-headers monads

我正在尝试阅读haskell中的websockets标题。

目前的代码如下

import Network
import Network.Socket.Internal
import Text.Printf
import Control.Monad
import Control.Monad.IO.Class
import Data.Maybe
import Data.List
import Data.Digest.Pure.SHA (bytestringDigest, sha1)
import Text.Regex
import System.IO

port :: Int
port = 8080

bufferLength :: Int
bufferLength = 2048

keyRegex :: String
keyRegex = "Sec-WebSocket-Key: (.+)(\r)"

response :: String
response = "HTTP/1.1 101 Web Socket Protocol Handshake\r\nUpgrade:     WebSocket\r\nConnection: Upgrade\r\nsec-websocket-accept:     changethis\r\n\r\n"

guidString :: String
guidString = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"

talk :: MonadIO m => Handle -> m String
talk handle = do liftIO $ hGetContents handle

main :: IO()
main = withSocketsDo $ do
  sock <- listenOn (PortNumber (fromIntegral port))
  printf "Listening on port %d\n" port
  forever $ do
    (handle, host, port) <- accept sock
    printf "Accepted connection from %s: %s\n" host (show port)
    hSetBuffering handle NoBuffering
    putStrLn $ talk handle

代码抛出错误

Main.hs:38:16:
    Couldn't match type `[Char]' with `Char'
    Expected type: String
      Actual type: [String]
    In the return type of a call of `talk'
    In the second argument of `($)', namely `talk handle'
    In a stmt of a 'do' block: putStrLn $ talk handle

如何打印标题字符串?对话功能应该获得标题字符串并将其返回打印。

1 个答案:

答案 0 :(得分:0)

talk handle的返回类型为(MonadIO m => m String)

putStrLn的类型为String -> IO ()[Char] -> IO ()

[]是一个monad。

putStrLn需要一个字符列表,但它的值为(MonadIO m => m String)

m成为一个列表,putStrLn获取类型为[String]的值,这是错误。


正如@Zeta建议的那样,改为使用talk handle >>= putStrLn

>>=是运算符,它允许继续使用另一个计算的结果进行计算。在您的情况下,您可以阅读talk handle >>= putStrLn,如下所示:

talk handle -- first compute it
  >>= putStrLn -- then take string from result of `talk handle` and print it

putStrLn $ talk handle

出现了任何错误
(>>=)                        :: Monad m => m a -> (a -> m b) -> m b
talk handle                  :: MonadIO m => m String
(>>=) (talk handle)          :: MonadIO m => (String -> m b) -> m b  
putStrLn                     :: String -> IO ()
(>>=) (talk handle) putStrLn :: IO () -- `m` becomes `IO`    

编辑:

在这里,您可以找到IO monad的简介:LYHFGG, Input and Output

在这里,你可以找到一般的monad介绍:LYHFGG, A Fistful of Monads

您应该了解FunctorApplicative,以便阅读A Fistful of Monads。无论如何,你可以在书的内容中找到它。