gpt4 book ai didi

Haskell Wikibook - 广义代数数据类型练习 - Maybe 和 Either

转载 作者:行者123 更新时间:2023-12-02 09:10:07 25 4
gpt4 key购买 nike

有一个关于 this page of the Haskell Wikibook 的练习这可以让您使用 Maybe 和 Either 完成一个场景(大概是为了表明这对于用例来说是相当痛苦的)。

练习是:

data Expr = I Int
| B Bool -- boolean constants
| Add Expr Expr
| Mul Expr Expr
| Eq Expr Expr -- equality test

eval :: Expr -> Maybe (Either Int Bool)
-- Your implementation here.

我认为解决方案的第一行很简单:

data Expr = I Int         -- integer constants
| B Bool -- boolean constants
| Add Expr Expr -- add two expressions
| Mul Expr Expr -- multiply two expressions
| Eq Expr Expr -- equality test
deriving (Show)

eval :: Expr -> Maybe (Either Int Bool)
eval (I n) = Just $ Left n
eval (B b) = Just $ Right b
eval (Add e1 e2) = ...
eval (Mul e1 e2) = ...
eval (Eq e1 e2) = ...

但我不太确定如何定义其余部分。作为一个例子,我想对于 add 我需要解压每个表达式的 fromLeftfromJust,但我不知道如何做到这一点正确(使用模式匹配?)

提前致谢!

最佳答案

是的,使用模式匹配,甚至可能使用Maybe monad。

您可以仅使用模式匹配来实现 eval (Add e1 e2) 分支:

eval (Add e1 e2) = case eval e1 of
Just (Left i1) -> case eval e2 of
Just (Left i2) -> Just (Left (i1 + i2))
_ -> Nothing
_ -> Nothing

一对上的模式匹配是减少嵌套 case 语句数量的好方法:

eval (Add e1 e2) = case (eval e1, eval e2) of
(Just (Left i1), Just (Left i2)) -> Just (Left (i1 + i2))
_ -> Nothing

或者,您可以使用 Maybe monad 作为这些 case 语句的抽象。如果 do block 绑定(bind)中的任何模式匹配失败,它将自动返回 Nothing (由于 Maybe monad 实现 fail 的方式) .

eval (Add e1 e2) = do
Left i1 <- eval e1
Left i2 <- eval e2
return (Left (i1 + i2))

关于Haskell Wikibook - 广义代数数据类型练习 - Maybe 和 Either,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53397200/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com