可能是Haskell数据类型的一部分

可能是Haskell数据类型的一部分,haskell,types,maybe,Haskell,Types,Maybe,比如说,我们想为某人的健康树立榜样。患者可能生病并患有流感、感冒、过敏或健康。在Haskell中,我们可以通过多种方式来定义这一点,其中两种方式是: data Condition = Flu | Cold | Allergy | Healthy 或 这类似于定义树结构,因为树元素可以是具有2个树的节点,或者为空: data Tree a = Node (Tree a) (Tree a) | Empty 或者也可以使用或者来定义树: data Node a = Node (Tree a) (T

比如说,我们想为某人的健康树立榜样。患者可能生病并患有流感、感冒、过敏或健康。在Haskell中,我们可以通过多种方式来定义这一点,其中两种方式是:

data Condition = Flu | Cold | Allergy | Healthy

这类似于定义
结构,因为
元素可以是具有2个
节点
,或者
为空

data Tree a = Node (Tree a) (Tree a) | Empty
或者也可以使用
或者
来定义

data Node a = Node (Tree a) (Tree a)
data Tree a = Tree (Maybe (Node a))
每种选择都有其利弊。在不使用
Maybe
的情况下,我们在单个数据声明中捕获
健康
的所有可能值,因此范围非常明确。另一方面,如果我们确实使用a
Mayb
e,那么我们就抓住了数据模型中可能存在或不存在某些东西的本质,避免创建空的定义数据类型,如
Empty
health
,而只使用
Nothing
来建模缺失。这稍微简化了模型,但是数据类型的声明不再包含在一段代码中


这两种方法的其他优点和缺点是什么?

显然,正如一些人指出的那样,给出的任何答案在某种程度上都是主观的。然而,代码不仅仅是让计算机执行计算的一种方式,它还是一种通信媒介

你越能清楚地向将来阅读代码的人传达你的意图,你就越能更好地解决这个问题。借鉴

显性比隐性好

这种启发式方法在许多不同的编程语言和场景中对我都很有用。一个推论是,在面向对象编程中,人们应该


我倾向于在类似OP的情况下应用类似的经验法则,如果显式命名的类型更好地传达意图,我会支持显式命名的类型。

显然,正如一些人指出的,给出的任何答案在某种程度上都是主观的。然而,代码不仅仅是让计算机执行计算的一种方式,它还是一种通信媒介

你越能清楚地向将来阅读代码的人传达你的意图,你就越能更好地解决这个问题。借鉴

显性比隐性好

这种启发式方法在许多不同的编程语言和场景中对我都很有用。一个推论是,在面向对象编程中,人们应该


<>我倾向于在OP这样的情况下应用类似的经验法则,如果他们能更好地传达意图,则支持明确命名的类型。

< P>我认为大部分的决定取决于你认为“代码>健康< /代码>是多么有意义。如果答案是“不太多”,那么您可能最好使用
Maybe
编码之类的方法(参见更明确案例的讨论)。顺便说一句,如果疾病不是相互排斥的,并且还有其他因素导致某种状况,我们就必须采用一种稍微不同的编码方式:

import qualified Data.Set as Set
import Data.Set (Set)

data Sickness = Flu | Cold | Allergy
    deriving (Eq, Ord)

data Alertness = Sleepy | Distracted | Caffeinated
    deriving (Eq, Ord)

data Condition = Condition (Set Sickness) (Set Alertness)
我觉得在这种情况下,将
健康
作为一种单独的条件将变得毫无意义

回到您最初的表述,值得一提的是有一个中间的第三种选择:滚动您自己的专业领域特定的
可能
(cf.):


这样做,您将错过
可能
处理工具,如果您想使用它们,您可能必须自己提供一些实例和函数(尽管这可能不是问题,取决于您计划如何使用
条件

< P>我认为大部分的决定取决于你认为“代码>健康< /代码>是多么有意义。如果答案是“不太多”,那么您可能最好使用
Maybe
编码之类的方法(参见更明确案例的讨论)。顺便说一句,如果疾病不是相互排斥的,并且还有其他因素导致某种状况,我们就必须采用一种稍微不同的编码方式:

import qualified Data.Set as Set
import Data.Set (Set)

data Sickness = Flu | Cold | Allergy
    deriving (Eq, Ord)

data Alertness = Sleepy | Distracted | Caffeinated
    deriving (Eq, Ord)

data Condition = Condition (Set Sickness) (Set Alertness)
我觉得在这种情况下,将
健康
作为一种单独的条件将变得毫无意义

回到您最初的表述,值得一提的是有一个中间的第三种选择:滚动您自己的专业领域特定的
可能
(cf.):


这样做,您将错过
可能
处理工具,如果您想使用它们,您可能必须自己提供一些实例和函数(尽管这可能不是问题,取决于您计划如何使用
条件
)。

挑剔:您实际上没有在代码中使用
可能
类型。短语
data sick=Maybe Condition
中的单词
Maybe
定义了一个名为
Maybe
的值构造函数,它恰好与名为
Maybe
的类型构造函数同名,纯粹是巧合。(类型和值在Haskell中存在于不同的名称空间中。)我猜您的意思是
data sick=sick(Maybe Condition)
,它定义了一个名为
sick
的值构造函数,参数类型为
Maybe Condition
@BenjaminHodgson是的,谢谢!编辑。更多挑剔:我会调整Benjamin的建议,将
疾病
条件
(即
数据条件=条件(可能疾病)
)的名称互换。这不是一个具体的编程问题,而是一个讨论问题。如果你真的遇到了这样一种情况,在真实的代码中出现了这种情况,你可以尝试转到codereview.stackexchange.com挑剔:你实际上没有在代码中使用
,可能是
类型。短语
data sick=Maybe Condition
中的单词
Maybe
定义了一个名为
Maybe
的值构造函数,它发生在
data Sickness = Flu | Cold | Allergy

data Condition = Healthy | Sick Sickness