产品类型转换为元组

Product type convert to tuple

我知道了

data Pair = P Int Double deriving Show
myP1 = P 1 2.0
getPairVal (P i d) = (i,d)
getPairVal' (P i d) = (,) i d

哪个有效,都产生 (1,2.0)。有什么方法可以让 (,) myP1 正常工作吗?但是我猜这需要某种“演员表”。

data Pair2 = P2 (Int, Double) deriving Show

是一种“更方便”的元组版本

myP21 = (5,5.0)

那么像 Pair 这样的产品类型有或没有元组类型定义的优势是什么?我似乎记得 SML 有更紧密的关系,即每个产品类型都是一个元组类型。在数学中,任何“产品”都会产生一个元组。 Haskell 显然不是。

why shouldn't a straight (,) myP1 work?

好吧,(,) 是一个函数,它接受两个值并从中生成一个元组。 P 1 2.0 而不是 两个值:它是 Pair 类型的单个值,它包含两个字段。但是 (,) (P 1 2.0) 是一个类型良好的表达式:它构建了元组的左半部分,右半部分还需要一个参数。所以:

let mkTuple = (,) (P 1 2.0) 
in mkTuple "hello" 

计算为

(P 1 2.0, "hello")

为什么我们应该像 Pair 这样定义类型而不是使用元组? user202729 在评论中链接到 Haskell: Algebraic data vs Tuple,这是对该问题的一个很好的回答。

但是您可以使用的另一种方法是定义一个 newtype 包装一个元组,这样您就有一个不同的命名类型,但具有与元组相同的运行时表示:

newtype Pair2 = P2 (Int, Double) deriving Show

如果您使用 newtype 而不是 data,您 do 会得到一个简单的转换函数,您可以选择将其视为转换: Data.Coerce.coerce。有了它,你可以写

myP21 = coerce (5, 5.0)

反之亦然。当您需要现有类型的新类型类实例时,主要使用此方法。如果您需要一个由两个值组成的新域类型,我仍然鼓励您默认使用具有两个字段的 data 类型,除非有令人信服的理由不这样做。