从 Either 返回定义的类型

Posted

技术标签:

【中文标题】从 Either 返回定义的类型【英文标题】:Returning defined type from Either 【发布时间】:2018-09-19 01:18:52 【问题描述】:

我声明了以下类型:

data Property = Property mapProperty :: !Object
                       deriving (Show, Generic)

我从以下函数返回该类型:

parseProps :: String -> IO (Either String Property)
parseProps m = fmap property <$> (eitherDecode <$> getMap m)

在调用函数中,我有以下内容:

pr <- liftIO $ parseProps t
let pro = case pr of
        Left err -> fail err
        Right pr -> pr

我从上面的行中得到以下错误(Right pr -> pr):

无法将预期类型“m a”与实际类型“Property”匹配 • 在表达式中:pr 在另一种情况下:Right pr -> pr 在表达式中:

    case pr of 
      Left err -> fail err
      Right pr -> pr 

• 相关绑定包括 pro :: m a (绑定在 src/Actor/Master.hs:42:7)

感谢您的帮助。

【问题讨论】:

【参考方案1】:

您的case 表达式具有不同类型的分支。 fail 具有 Monad m =&gt; String -&gt; m a 类型(因此 fail err 具有 Monad m =&gt; m a 类型)并且 prProperty

这就是 m aProperty 不匹配的原因。

如果您希望它们匹配,您需要将Property 转换为m Propertyreturn

像这样:

pr <- liftIO $ parseProps t
pro <- case pr of
    Left err -> fail err
    Right pr -> return pr
...

然后用pro做这些事情

此外,正如 Jon Purdy 和 Paul Johnson 在 cmets 中指出的那样,有一个用于此操作的组合子 either。所以这是一种更简洁的写法:

pr <- liftIO $ parseProps t
pro <- either fail return pr

【讨论】:

这也可以用either组合器写得更简洁,例如:pro &lt;- either fail pure pr @JonPurdy 或pro &lt;- either fail return pr。初学者可能不知道pure == return @PaulJohnson:哎呀,是的,习惯的力量。我现在总是使用pure,因为它更通用(Applicative 而不是Monad)而且我更喜欢这个名字——pure x 将纯值x 转换为一个动作(对于大多数单子来说“return”x),而return xreturn 关键字的faux ami,用于以命令式语言从过程中(提前)退出。

以上是关于从 Either 返回定义的类型的主要内容,如果未能解决你的问题,请参考以下文章

在 Haskell 中组合任何类型的绑定

如何绑定多个Either<,>?

05.either 方法

matlab错误:Subscript indices must either be real positive integers or logicals.

Arrow-kt:如何将 Either<E, List<Either<E,A>>> 变成 Either<E, List<B>>

如何在flutter中将Either Right初始化为空值