Hask 中的型別產品

分類產品

在類別理論中,兩個物體 XY 的乘積是另一個具有兩個投影的物體 Zπ1:Z→Xπ2:Z→Y ; 使得來自另一個物體的任何其他兩個態射通過這些投射唯一地分解。換句話說,如果存在 f 1:W→Xf 2:W→Y ,則存在唯一的態射 g:W→Z ,使得 π1○g = f 1π2○g = f 2

哈斯克的產品

這轉化為 Hask Haskell 的型別的類別如下,ZAB 時的產品:

-- if there are two functions
f1 :: W -> A
f2 :: W -> B
-- we can construct a unique function
g  :: W -> Z
-- and we have two projections
p1 :: Z -> A
p2 :: Z -> B
-- such that the other two functions decompose using g
p1 . g == f1
p2 . g == f2

按照上述規律**,兩種型別** AB產品型別是 (A,B) 的兩種型別的元組,兩個投影是 fstsnd。我們可以檢查它是否符合上述規則,如果我們有兩個函式 f1 :: W -> Af2 :: W -> B 我們可以唯一地分解它們如下:

decompose :: (W -> A) -> (W -> B) -> (W -> (A,B))
decompose f1 f2 = (\x -> (f1 x, f2 x))

我們可以檢查分解是否正確:

fst . (decompose f1 f2) = f1
snd . (decompose f1 f2) = f2

同構性的唯一性

(A,B) 作為 AB 的產品的選擇並不是唯一的。另一個合乎邏輯的等價選擇是:

data Pair a b = Pair a b

而且,我們也可以選擇 (B,A) 作為產品,甚至是 (B,A,()),我們也可以按照規則找到類似上面的分解函式:

decompose2 :: (W -> A) -> (W -> B) -> (W -> (B,A,()))
decompose2 f1 f2 = (\x -> (f2 x, f1 x, ()))

這是因為產品不是唯一的,而是同構的獨特之AB 的每兩個產品不必相等,但它們應該是同構的。舉個例子,我們剛剛定義的兩個不同的產品 (A,B)(B,A,()) 是同構的:

iso1 :: (A,B) -> (B,A,())
iso1 (x,y) = (y,x,())

iso2 :: (B,A,()) -> (A,B)
iso2 (y,x,()) = (x,y)

分解的唯一性

值得注意的是,分解函式也必須是唯一的。有些型別遵循產品所需的所有規則,但分解並不是唯一的。舉個例子,我們可以嘗試使用 (A,(B,Bool)) 作為 AB 的產品:fst fst . snd

decompose3 :: (W -> A) -> (W -> B) -> (W -> (A,(B,Bool)))
decompose3 f1 f2 = (\x -> (f1 x, (f2 x, True)))

我們可以檢查它是否有效:

fst         . (decompose3 f1 f2) = f1 x
(fst . snd) . (decompose3 f1 f2) = f2 x

但問題是我們可以編寫另一個分解,即:

decompose3' :: (W -> A) -> (W -> B) -> (W -> (A,(B,Bool)))
decompose3' f1 f2 = (\x -> (f1 x, (f2 x, False)))

並且,由於分解不是唯一的(A,(B,Bool)) 不是 Hask 中的 AB產物