gpt4 book ai didi

haskell - 如何使函数仅可用于 ADT 的某个数据构造函数?

转载 作者:行者123 更新时间:2023-12-04 18:04:12 25 4
gpt4 key购买 nike

我目前正在 Haskell 中使用 ADT,并尝试构建一个 ADT Figure :

data Figure = Rect { x :: Integer, y :: Integer, width :: Integer, height :: Integer}
| Circle { x :: Integer, y :: Integer, radius :: Integer}
| CombiFigure Figure Figure
deriving (Eq, Show, Read)

现在我遇到了如何实现一个不应该接受每个 Figure 的函数的问题。 ,但例如只有一个 Circle .

我已经有一个糟糕的设计了吗?或者是否有一些最佳实践如何做到这一点?

例如,考虑一个直径函数。我想到的所有(我是 Haskell 的完全初学者)是以下两个选项,使用 undefinedMaybe :

1:
diameter :: Figure -> Integer
diameter (Circle _ _ r) = 2 * r
diameter _ = undefined

2:
diameter :: Figure -> Maybe Integer
diameter (Circle _ _ r) = Just (2 * r)
diameter _ = Nothing

有没有更可取的方法来实现这一目标?
谢谢!

最佳答案

你说得对,这里有些不对劲。最好的思考方式是从函数 diameter 开始。并决定理想情况下它的类型应该是什么。你可能会想出

diameter :: Circle -> Integer
diameter (Circle _ _ r) = 2 * r

因为直径只为圆定义。

这意味着您必须通过拆分 Circle(以及 Rect)来扩充数据结构:
data Figure = RectFigure Rect
| CircleFigure Circle
| CombiFigure Figure Figure
deriving (Eq, Show, Read)

data Rect = Rect { rectX :: Integer, rectY :: Integer, rectWidth :: Integer, height :: Integer}
deriving (Eq, Show, Read)

data Circle = Circle { circleX :: Integer, circleY :: Integer, circleRadius :: Integer}
deriving (Eq, Show, Read)

这很好,因为它现在更灵活:您可以编写不关心什么的函数 Figure它们适用于,您可以编写在特定 Figure 上定义的函数s。

现在,如果我们在一个更高级的函数中并且有一个对 Figure 的引用。我们想计算它的 diameter如果是 CircleFigure ,那么您可以使用模式匹配来做到这一点。

注意:使用 undefined或异常(在纯代码中)可能是代码异味。它可能可以通过重新考虑您的类型来解决。如果必须指示失败,请使用 Maybe/ Either .

关于haskell - 如何使函数仅可用于 ADT 的某个数据构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34964015/

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