フィールドsTypeを持つデータ型を、(zeromq-haskellの)STypeのインスタンスであるものとして表現したいと思います。 STypeはzeromqソケットタイプです。Haskell typeclassのインスタンスとしてのデータフィールド
Ambiguous type variable `a0' in the constraint:
(SType a0) arising from a use of `sType'
:
data Pair = Pair
instance SType Pair where
zmqSocketType = const pair
ここで私は今
data SocketOpts = SocketOpts
{ end :: SocketEnd
, sType :: SType st => st
}
を持っているしかし、私はそうsocket ctx $ sType so
のようにそれを使用するときに私が得るものです:zeromq-Haskellのソースでは1例がこれです(ソケットの署名はsocket :: SType a => Context -> a -> IO (Socket a)
私はSocketOpt GHCiの中のSは、私が手:私はこのことから理解することはSTYPEは、私が求めてきたもの(STYPEのインスタンスである、プル)ことがより一般的であるということです
let so = SocketOpts (Bind "some") Pull
<interactive>:1:35:
Could not deduce (st ~ Pull)
from the context (SType st)
bound by a type expected by the context: SType st => st
at <interactive>:1:10-38
`st' is a rigid type variable bound by
a type expected by the context: SType st => st
at <interactive>:1:10
In the second argument of `SocketOpts', namely `Pull'
In the expression: SocketOpts (Bind "some") Pull
In an equation for `so': so = SocketOpts (Bind "some") Pull
。私はここで何をしたいのですか?
編集
この:と一緒に使用されている
data SocketOpts st = SocketOpts
{ end :: SocketEnd
, sType :: st
}
:
zmqSource :: (ResourceIO m, SType st) => Context -> SocketOpts st -> Source m a
zmqSource ctx so = sourceIO
mkSocket
recvSock
(\x -> undefined)
where
recvSock = undefined
mkSocket = socket ctx $ sType so
が動作しているようだが、私は中に未解決の問題を残しておきます場合は、これを行うよりエレガントな方法がありますか?
編集2
みんな、あなたの答えに心より感謝申し上げます。あなたのフィードバックに基づいて、私は今(それはgithubの上で読みやすいですと、私はここに掲載しません)、次の
https://github.com/boothead/zeromq-conduit/blob/master/Data/Conduit/ZMQ.hs
を持っている私が試してみて、表現するためにGADTを(と思う)使用しました通常のソケットとSubソケットの設定の違いですが、現時点ではシワがあります:SockOptsタイプを使用してサブソケットを設定することができます。サブスクリプションは呼び出されず、動作しません。
SockOpts (Connect "tcp://127.0.0.1:9999") Sub -- This would be bad
これを禁止するようにタイプシステムを取得する方法はありますか。山括弧に入っているもののようなもの?
SockOpts :: (SType st, <not SubsType st>) => SocketEnd -> st -> SocketOpts st