type ErrorOrValue = Either InterpreterError Value
evaluateExpression :: [Value] -> IR.Expression -> ErrorOrValue
evaluateExpression as (IR.Application l r)
| Left _ <- arg = arg
| Right (Partial ac b as) <- f = foo as f arg
| Right _ <- f = Left NonFunctionApplication
| otherwise = f
where
f = evaluateExpression as l >>= forceValue
arg = evaluateExpression as r
我需要使用foo
和f
致电arg
,确保它们不是Left
。
我可以减少模式匹配,而是使用绑定和其他monad操作吗?
答案 0 :(得分:5)
我需要使用
foo
和f
致电arg
,确保它们不是Left
。
为此,您可以将Applicative
实例用于Either
。
foo <$> f <*> arg
或
liftA2 foo f arg
如果f
和arg
为Right
值,则会提取这些值,将foo
应用于它们并在Right
构造函数中回复。如果f
或arg
值为Left
,则会返回该值(如果两者都为f
,则会有Left
的值。)
答案 1 :(得分:1)
您可以使用do
。您的代码会在arg
之前检查f
,而foo
似乎会返回ErrorOrValue
,因此无需将其提升到Monad
。此外,传递给as
的{{1}}是从foo
中提取的,而不是Partial
的参数。这是一些完全未经测试的代码:
evaluateExpression