无法将类型“Either String”与“[]”匹配

Couldn't match type ‘Either String’ with ‘[]’

我有这个主要方法:

main :: IO ()
main = do 
     x <- getArgs
     case x of
         [] -> putStrLn "Empty"
         [x] ->  putStrLn (split x >>= (\(a,b) -> a ++ " " ++ b))
         _ -> putStrLn "More than one argument"

其中 split 函数定义为:

split :: String -> Either String (String, String)

我在这里做错了什么?我想在这里做的只是打印从 split 函数

返回的元组
putStrLn (split x >>= (\(a,b) -> a ++ " " ++ b))

单子绑定运算符 >>= 具有签名

(>>=) :: Monad m => m a -> (a -> m b) -> m b

或者,根据您的具体情况,

(>>=) :: Either e a -> (a -> Either e b) -> Either e b

所以我们使用 >>= 当我们有一个 Either 并且想将它里面的东西传递给一个本身 return 是 Either 的函数。但是你的函数是 \(a,b) -> a ++ " " ++ b),它不是 return 和 Either。你想要做的是拿一个 Either 并将函数应用到内部,单独留下 Either 部分。这是 Functor 类型类中 fmap 的用法。

fmap :: Functor f => (a -> b) -> f a -> f b
-- Specifically
fmap :: (a -> b) -> Either e a -> Either e b

所以你想要

fmap (\(a,b) -> a ++ " " ++ b) $ split x

这将 return 一个 Either String StringputStrLn是用来打印字符串的。如果我们要打印Either,那么就需要使用print.

print (fmap (\(a,b) -> a ++ " " ++ b) $ split x)

另一方面,我们可以对结果进行模式匹配,并在 Left 情况下做一些不同的事情。

case fmap (\(a,b) -> a ++ " " ++ b) $ split x of
  Left e -> undefined -- Error case
  Right s -> putStrLn s