gpt4 book ai didi

haskell - 如何摆脱 "Ambiguous type variable ` 消息 0' in the constraints"

转载 作者:行者123 更新时间:2023-12-04 18:19:13 25 4
gpt4 key购买 nike

我对 Haskell 中的 Protocol Buffer 有疑问。我正在编写一个简单的 UDP 接收器并得到错误:

src/Main.hs:39:25:
Ambiguous type variable `msg0' in the constraints:
(Wire msg0)
arising from a use of `messageGet' at src/Main.hs:39:25-34
(Text.ProtocolBuffers.Reflections.ReflectDescriptor msg0)
arising from a use of `messageGet' at src/Main.hs:39:25-34
Probable fix: add a type signature that fixes these type variable(s)
In the expression: (messageGet (B.pack mesg))
In the second argument of `($)', namely
`case (messageGet (B.pack mesg)) of {
Left person -> putStrLn $ show person
Right err -> error $ "Failed to parse address book." }'
In a stmt of a 'do' block:
return
$ case (messageGet (B.pack mesg)) of {
Left person -> putStrLn $ show person
Right err -> error $ "Failed to parse address book." }

我怎样才能听从它的建议? (我只是在学习 Haskell。)

我的代码如下:
module Main where

import Data.Bits
import Network.Socket -- hiding (send, sendTo, recv, recvFrom)
-- import Network.Socket.ByteString
import Network.BSD
import Data.List
import qualified Data.ByteString.Lazy.Char8 as B
import Text.ProtocolBuffers.Header (defaultValue, uFromString)
import Text.ProtocolBuffers.WireMessage (messageGet, messagePut, Wire)

import Data.Sequence ((><), fromList)

import AddressBookProtos.AddressBook
import AddressBookProtos.Person
import AddressBookProtos.Person.PhoneNumber
import AddressBookProtos.Person.PhoneType

import Network.Socket
import System.Posix.Directory
import System.Posix.Files
import System.Posix.IO
import System.Posix.Process
import System.Exit


echoserver :: IO ()
echoserver = do
withSocketsDo $ do
sock <- socket AF_INET Datagram 0
bindSocket sock (SockAddrInet 4567 iNADDR_ANY)
socketRx sock

socketRx :: Socket -> IO ()
socketRx sock = do

(mesg, recv_count, client) <- recvFrom sock 1500

return $ case (messageGet (B.pack mesg)) of
Left person -> putStrLn $ show person
Right err -> error $ "Failed to parse address book."
socketRx sock



main::IO()
main = echoserver

最佳答案

来自 http://hackage.haskell.org/packages/archive/protocol-buffers/2.0.9/doc/html/Text-ProtocolBuffers-WireMessage.html#v:messageGet 的文档, messageGet 的类型签名是

messageGet :: (ReflectDescriptor msg, Wire msg) => ByteString -> Either String (msg, ByteString)

返回值是 String错误消息或 msg和一个残差 ByteString .在您的代码中,您已经编写了
case messageGet (B.pack mesg) of
Left person -> putStrLn $ show person
Right err -> error "Failed to parse address book."

如果返回 (msg, ByteString) ,该值绑定(bind)到变量 err .由于 err被忽略, msg 的实际类型未确定,这是错误消息告诉您的内容。事实上,任何作为 Wire 实例的类型和 ReflectDescriptor会起作用,但程序对于每种类型的行为都会有所不同!由于编译器不知道你想要什么类型,你必须指定它。您可以通过注解 messageGet 的返回类型来指定它.
case messageGet (B.pack mesg) :: Either String (X, ByteString) of -- Use the actual message type in place of 'X'
Left person -> putStrLn $ show person
Right err -> error "Failed to parse address book."

您可能还打算切换 LeftRight您的代码中的案例。 Right是非错误情况(认为“错误”和“正确”)。切换案例不会自行消除错误消息。

关于haskell - 如何摆脱 "Ambiguous type variable ` 消息 0' in the constraints",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11033236/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com