Haskell 从 Get monad 获取 Either 的值

Haskell getting value of Either from Get monad

我是一个 Haskell 菜鸟,感觉卡在了我试图执行的一个相当简单的功能上。最终我的目标是阅读严格的 ByteString,使用带有解码器的 Get monad 从 ByteString 中检索第一个 Word32,并执行特定功能 [=17] =] 在 Word32.

的各个部分上的计算结果为 True

这是我的示例代码:

import Data.List
import Data.Char
import Data.Function
import System.Random
import Data.Bits
import Data.Either
import Data.Binary.Strict.Get
import System.IO as SIO
import Data.ByteString.Char8 as B
import Data.Word (Word32)
import Data.ByteString.UTF8 as BU

dateTemplate = "YYMMDDhhmmss"

convertFromString :: String -> ByteString
convertFromString s = BU.fromString s

mahDecoder :: Get Word32
mahDecoder = do
  first32Bits <- getWord32be
  return first32Bits

main :: IO ()
main = do 
  let a = runGet mahDecoder (convertFromString dateTemplate)
  SIO.putStrLn $ show a

  -- When I uncomment these lines I get the problem

  --case a of
  --  Left val -> SIO.putStrLn "Communist!"
  --  Right val -> SIO.putStrLn $ "Fascist!"

当我 运行 解码器上的 runGet 函数并在 main 中传递我的 ByteString 时,我可以看到它 returns 一个像这样的 Either 实例:

(Right 1499024717,"DDhhmmss")

当我尝试在 Left 或 Right 上进行大小写时,它失败并出现以下错误:

HSWhosebugExamp.hs:31:5:
    Couldn't match expected type `(Either String Word32, ByteString)'
                with actual type `Either t0 t1'
    In the pattern: Left val
    In a case alternative: Left val -> SIO.putStrLn "Communist!"
    In a stmt of a 'do' block:
      case a of {
        Left val -> SIO.putStrLn "Communist!"
        Right val -> SIO.putStrLn $ "Fascist!" }

知道我在这里做错了什么吗?我觉得我应该用解码器从 ByteString 读取所有字节。老实说,我不完全确定 a 是什么类型。我对 Monad 和 Monad Transformers 的了解仍然非常有限。我希望我不需要掌握每一种 Haskell 黑暗艺术,就可以实现即使是简单的练习用例。如果答案是继续阅读,那么我接受。

a 的类型是第一项是 Either 的元组。尝试将您的案例陈述更改为:

case a of
    (Left val, _) -> SIO.putStrLn "Communist!"
    (Right val, _) -> SIO.putStrLn $ "Fascist!"