gpt4 book ai didi

haskell - Haskell 中产品类型和元组的冗余

转载 作者:行者123 更新时间:2023-12-02 10:08:54 26 4
gpt4 key购买 nike

在 Haskell 中,你有产品类型和元组。

如果您不想将专用类型与值关联,则可以使用元组;如果您愿意,可以使用产品类型。

但是我觉得产品类型的符号有冗余

data Foo = Foo (String, Int, Char)
data Bar = Bar String Int Char

为什么有两种表示法?有没有什么情况你会更喜欢其中一个?

我猜你在使用元组时不能使用记录符号,但这只是一个便利问题。另一件事可能是元组中的顺序概念,而不是产品类型,但我认为这只是由于函数 fstsnd 的命名所致。

最佳答案

@chi's answer是关于Haskell评估模型方面的技术差异。我希望能让您深入了解这种类型化编程的哲学。

在范畴论中,我们通常处理“直到同构”的对象。您的 Bar 当然与 (String, Int, Char) 同构,因此从分类角度来看它们是相同的东西。

bar_tuple :: Iso' Bar (String, Int, Char)
bar_tuple = iso to from
where to (Bar s i c) = (s, i, c)
from (s, i, c) = Bar s i c

在某种意义上,元组是产品类型的柏拉图式形式,因为它们除了作为不同值的集合之外没有任何意义。所有其他产品类型都可以映射到普通旧元组或从普通旧元组映射。

当所有 Haskell 类型最终都归结为乘积之和时,为什么不到处使用元组呢?这是关于沟通的。正如马丁·福勒所说,

Any fool can write code that a computer can understand. Good programmers write code that humans can understand.

名字很重要!写下自定义产品类型,例如

data Customer = Customer { name :: String, address :: String }

Customer 类型赋予阅读代码的人含义,这与 (String, String) 不同,(String, String) 仅表示“两个字符串” .

当您想要通过隐藏数据的表示并使用智能构造函数来强制不变量时,自定义类型特别有用:

newtype NonEmpty a = NonEmpty [a]

nonEmpty :: [a] -> Maybe (NonEmpty a)
nonEmpty [] = Nothing
nonEmpty xs = Just (NonEmpty xs)

现在,如果您不导出 NonEmpty 构造函数,则可以强制人们使用 nonEmpty 智能构造函数。如果有人给您一个 NonEmpty 值,您可以放心地假设它至少有一个元素。

您当然可以将 Customer 表示为底层的元组,并公开具有令人回味的命名的字段访问器,

newtype Customer = Bar (String, String)
name, address :: Customer -> String
name (Customer (n, a)) = n
address (Customer (n, a)) = a

但这并没有给你带来多大的好处,除了现在将 Customer 转换为元组更便宜(如果,比方说,你正在编写与元组一起使用的性能敏感的代码)面向API)。

如果您的代码旨在解决某个特定问题(这当然是编写代码的全部意义),那么不仅要解决问题,还要让它看起来像是您也解决了问题。有人(也许是几年后的你)将不得不阅读这段代码并理解它,而先验不知道它是如何工作的。在这方面,自定义类型是一个非常重要的沟通工具。

关于haskell - Haskell 中产品类型和元组的冗余,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43046668/

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