作为用Haskell编写的大型项目的一部分,我正在开发一个小型实用程序库来封装我在整个代码中使用的常见范例。我正在处理的一个函数(或两个函数)是fromLeft :: Either a b -> a
和fromRight :: Either a b -> b
,它们是在反病毒构造函数上未定义的部分函数(error
):
fromLeft :: Either a b -> a
fromLeft x = case x of
(Left x) -> x
(Right y) -> error "fromLeft: (Right _)"
fromRight :: Either a b -> b
fromRight x = case x of
(Right x) -> x
(Left y) -> error "fromRight: (Left _)"
在任何情况下,如果可能的话,我想扩展这些函数,这样,如果第二个模式中的y
匹配每个函数的类型都是show
,那么它将被打印出来而不是"_"
。但是,没有明显的方法可以解决这个问题而不对签名设置约束,这会使这些功能失去一般性。
是否有任何扩展或模块voodoo可以选择性地为这些类型类的实例执行类型类函数并返回其他类型的一般结果?更具体地说,Haskell中是否有任何方法可以编写模拟无效函数的程序
\x -> if (showable x) then show x else "_"
答案 0 :(得分:4)
这个怎么样:
fromRightWith :: (a -> String) -> Either a b -> b
fromRightWith show (Left a) = error $ "fromRight: (Left " ++ show a ++ ")"
fromRightWith _ (Right b) = b
fromRight :: Either a b -> b
fromRight = fromRightWith $ const "_"
fromRight' :: Show a => Either a b -> b
fromRight' = fromRightWith show
然后,如果您在代码中知道a
是Show
的实例,请使用fromRight'
。如果没有,请使用fromRight
:
instance Show MyError where
show = -- ..
trySomething :: IO (Either MyError Value)
trySomething = --- ..
main = do
value <- fromRight' <$> trySomething
-- ..