从ByteString读取ADT

时间:2018-03-31 16:10:09

标签: haskell

假设我们有类似

的数据类型
data Letter = A | B | C

我们得到一个包含“A”的ByteString输入。 我们如何轻松地将ByteString转换为Letter类型?

P.S。我找到了执行此操作的Readable库,但它返回MonadPlus(我不是很熟悉),而不是我期望的Maybe Letter

编辑:

这是我正在为上下文工作的简单HTTP应用程序。我似乎无法通过此获得Maybe Letter

import Network.Wai
import Network.HTTP.Types
import Network.Wai.Handler.Warp (run)

app :: Application
app request respond = let letter :: Maybe Letter
                          letter = fmap fromBS $ getParam request "letter"
                      respond $ responseLBS status200
                                            [("Content-Type", "text/plain")]
                                            "hello"

getParam request name = join (lookup name (queryString request))

编译器抱怨类型错误,我无法弄清楚如何捕获这两种类型m0a0,即使我在第7行写了类似let letter :: Maybe (Letter, ByteString)的内容代替。

• Couldn't match type ‘m0 a0’ with ‘Letter’
  Expected type: Maybe Letter
  Actual type: Maybe (m0 a0)

3 个答案:

答案 0 :(得分:4)

键入未测试:

Blob blob = blobStore.blobBuilder(file.getName())
    .payload(fileBytes)
    .contentLength(file.length()
    .contentType(contentType)
    .userMetadata(ImmutableMap.of("test", String.valueOf(strValue)))
    .build();

答案 1 :(得分:2)

一般方法是派生Read实例,该实例提供来自String的反序列化:

data Letter = A | B | C deriving (Read)

通过readreadsreadMaybe以及Text.Read中定义的其他变体,然后使用转化函数(例如Data.ByteString.Char8.unpack,如果是字节string是ASCII或Latin-1)从bytestring转换为字符串。

你要做的事情的细节有点模糊。 (例如,如果bytestring是“ABC”,您是否要解析“A”并保存“BC”以供日后使用,或者是否应该生成Nothing。)但是,以下内容可能会让您开始:

import Text.Read
import qualified Data.ByteString.Char8 as C

data Letter = A | B | C deriving (Show, Read)

readLetter :: C.ByteString -> Maybe Letter
readLetter = readMaybe . C.unpack

在GHCi中测试:

> :set -XOverloadedStrings
> readLetter "A"
Just A
> readLetter "B"
Just B
> readLetter "X"
Nothing
> readLetter "ABC"
Nothing
>

答案 2 :(得分:2)

  

它返回一个MonadPlus(我不太熟悉)

Maybe有一个MonadPlus个实例,所以你可以使用它。