从 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 => String -> m a
类型(因此 fail err
具有 Monad m => m a
类型)并且 pr
是 Property
。
这就是 m a
与 Property
不匹配的原因。
如果您希望它们匹配,您需要将Property
转换为m Property
和return
。
像这样:
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 <- either fail pure pr
@JonPurdy 或pro <- either fail return pr
。初学者可能不知道pure == return
。
@PaulJohnson:哎呀,是的,习惯的力量。我现在总是使用pure
,因为它更通用(Applicative
而不是Monad
)而且我更喜欢这个名字——pure x
将纯值x
转换为一个动作(对于大多数单子来说“return”x
),而return x
是return
关键字的faux ami,用于以命令式语言从过程中(提前)退出。以上是关于从 Either 返回定义的类型的主要内容,如果未能解决你的问题,请参考以下文章
matlab错误:Subscript indices must either be real positive integers or logicals.
Arrow-kt:如何将 Either<E, List<Either<E,A>>> 变成 Either<E, List<B>>