文本包不提供编码/解码文本的Binary
实例。我已经阅读并理解了这背后的原因(即,Text
应该是编码不可知的)。但是,我需要一个Binary
Text
实例。我发现有一个名为text-binary的包可以做到这一点。但是,实例如下:
instance Binary T.Text where
put = put . T.encodeUtf8
get = T.decodeUtf8 <$> get
非常好,除了decodeUtf8
是部分函数,所以我宁愿使用decodeUtf8'
并将失败传递给Get
monad。我无法弄清楚如何使用Get
monad正确失败。只是在Data.Binary.Get中查看,我看到了:
data Decoder a = Fail !B.ByteString {-# UNPACK #-} !ByteOffset String
| Partial (Maybe B.ByteString -> Decoder a)
| Done !B.ByteString {-# UNPACK #-} !ByteOffset a
这似乎表明有办法做我想做的事。我只是看不出图书馆作者打算如何使用它。我很欣赏任何比我自己更有学问的见解。
答案 0 :(得分:4)
好吧,虽然我们倾向于忽略它,Monad
类仍然有那种令人讨厌的fail
方法:
get = do
utf8'd <- get
case T.decodeUtf8' utf8'd of
Just t -> return t
Nothing -> fail "No parse for UTF-8 Text"
我不确定使用fail
是否仍应被视为“正确”,但对于这样的案例来说,这似乎是显而易见的。我想即使它已从Monad
类中移除,也会有一些其他class MonadPlus m => MonadFail m where fail :: String -> m a
Get
将成为其实例。