我正在尝试阅读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
如何打印标题字符串?对话功能应该获得标题字符串并将其返回打印。
答案 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。
您应该了解Functor
和Applicative
,以便阅读A Fistful of Monads
。无论如何,你可以在书的内容中找到它。