开发者

Reduce the pattern matching

开发者 https://www.devze.com 2023-04-07 15:50 出处:网络
type ErrorOrValue = Either 开发者_开发技巧InterpreterError Value evaluateExpression :: [Value] -> IR.Expression -> ErrorOrValue
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

I need to call foo with f and arg making sure that they are not Left.

Can I reduce the pattern matching and instead use binds and other monad operations?


I need to call foo with f and arg making sure that they are not Left.

For this, you can use the Applicative instance for Either.

foo <$> f <*> arg

or

liftA2 foo f arg

If f and arg are Right values, this will extract those, apply foo to them and give the answer back in a Right constructor. If either f or arg are Left values, that value will be returned (favoring the one from f if both are Left).


You can use do. Your code checks arg before f, and foo appears to return an ErrorOrValue, so it does not need to be lifted into the Monad. Also, the as that is passed to foo is that extracted from the Partial, not the argument to evaluateExpression. Here is some completely untested code:

type ErrorOrValue = Either InterpreterError Value 

evaluateExpression :: [Value] -> IR.Expression -> ErrorOrValue

evaluateExpression as (IR.Application l r) =
    do arg <- evaluateExpression as r
       f <- evaluateExpression as l >>= forceValue
       case f of
           Partial ac b as -> foo as f arg
           otherwise -> Left NonFunctionApplication
0

精彩评论

暂无评论...
验证码 换一张
取 消