- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在 Haskell 中,你有产品类型和元组。
如果您不想将专用类型与值关联,则可以使用元组;如果您愿意,可以使用产品类型。
但是我觉得产品类型的符号有冗余
data Foo = Foo (String, Int, Char)
data Bar = Bar String Int Char
为什么有两种表示法?有没有什么情况你会更喜欢其中一个?
我猜你在使用元组时不能使用记录符号,但这只是一个便利问题。另一件事可能是元组中的顺序概念,而不是产品类型,但我认为这只是由于函数 fst
和 snd
的命名所致。
最佳答案
@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/
我有下面提供的“示例代码”,我觉得这很多余,并且想请您与我一起解释是否有任何更少冗余的方法来处理以下代码。 public interface Bars { FOO1 FOO1 = (FOO1)
我们刚刚测试了一个由 2 个服务器组成的 AppFabric 集群,我们在其中删除了“领导”服务器。第二个服务器对它的任何请求超时并出现错误: Microsoft.ApplicationServer.
我正在设计一个关系数据库 - 底层是 MySQL - DBDesigner 4 . 我有 3 个表:module、page 和 lang。每个模块属于一个页面,每个页面都有特定的语言: 外键 pag
我的 Fraction 程序运行流畅,但 NetBeans IDE 告诉我以下 if 是多余的: public boolean equals(Object other) { Fraction bo
下面的代码显然是多余的,但根据我的经验,我经常使用这种模式。有没有更好的方法在 python 中执行此操作? if re.search("at (\d{1,2}):\d{2}", p): a=
我有一个用具体示例说明的一般性问题。当所有组件对象都已测试时,您建议对复合对象进行多少测试? 作为具体示例,请考虑下面的 NullTerminatedStringReader。它从字节缓冲区中读取一个
if ( a > b) { return true; } return false; 对于上面的代码,Netbeans 给出了 “Redundant if statement” 警告并建议将其更改
当我添加一些约束时,例如: create table Test( IDTest int primary key, Credit int not null constraint Credit
此代码适用于 Microchip 的 PIC32MX 微处理器。他们的编译器本质上是 GCC 3.4。 我倾向于使用 GCC 的 __packed__ attribute将位域打包到一个 union
已关闭。这个问题是 not reproducible or was caused by typos 。目前不接受答案。 这个问题是由拼写错误或无法再重现的问题引起的。虽然类似的问题可能是 on-top
我正在为我的应用程序使用apns通知,为此,我将apns设备 token 存储在我的sql数据库中。 问题在于,每次用户删除或安装该应用程序时,它都会生成一个新的设备 token ,并将其存储在数据库
Action Keyname Type Unique Packed Column Cardinality Collation Null Comment Edit Dro
我正在开发一个使用 ARM Cortex-M0 处理器的项目。在这个项目中,我需要提供计时器支持(CMSDK (SSE-200)计时器)。 因此,在 vector 表中,在 TIMER0_IRQn 表
有没有写的理由 corsFilter.setAllowedOrigins(new HashSet(Arrays.asList("*"))); 其中allowedOrigins在ReSTLet框架中的定
我正在创建一个包含 4 个链接的 HTML/CSS 页面, Home.html Details.html ContactMe.html AboutUs.html 我想在所有关联的 HTML 页面中将其
我试图理解并使用其他人编写的代码,但由于我对 typedef 经验不多。 , 我有时会感到困惑。 有两个不同的头文件,一个继承另一个,并且在两个文件上声明相同的typedef。 为什么会出现冗余,如何
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我有一个用于改造的 POJO 类。 public class AppData(){ String a; String b; String c;
我想知道: 编写这段代码: DataRow[] g = new DataRow[1] ; var t=new StringBuilder().AppendFormat("{0}", g[0]["a
只是一个性能问题...... 假设我有 5 个类,每个类都引用了 System.Data 和一个自己开发的库。这 5 个类是类库的一部分,最终将被构建并发布到一些 Web 应用程序作为引用。 通过将引
我是一名优秀的程序员,十分优秀!