考慮以下幾點:在沒有專門使用構造函數的情況下獲取GADT風格聲明中的約束?
{-# LANGUAGE GADTs, GADTSyntax #-}
data Test a where
Test :: Ord a => { first :: a, second :: a } -> Test a
comp :: Test a -> Bool
comp (Test fst snd) = fst < snd
構造Test
與一個Ord
約束聲明。在comp
,我已經明確採取Test
構建的參數,這給Ord
約束允許我使用<
現在,假設我想寫:
comp' :: Test a -> Bool
comp' x = (first x) < (second x)
使用投影功能,以獲得第一和第二元素。這是而不是沒問題,因爲我的參數x
不是(必然)用Test
構建的,所以沒有Ord
約束。
所以,我的問題,是有辦法把參數作爲剛剛x
但仍不知爲什麼從Test
構造的Ord
約束,而不必「解壓」或在Test
構造模式匹配或添加約束我的功能?
至於爲什麼我想這一點,我有一個構造數據類型採取了許多價值觀,其中之一,我只需要在這個特殊的功能,所以拆包它使我的功能不必要的冗長:
myFunction :: Thing -> ...
myFunction (Thing _ _ _ _ need _ _) ...
與之相對
myFunction t = ... (need t)
您可以使用'myFunction t @ Thing {} = ...'。 – Alec
'myfunction Thing {need = x}'這提供了'Ord'字典,而且'need'字段的值也已經解壓到'x'中。還有一個擴展可以讓你編寫'myFunction Thing {need}',並且在主體中你可以使用'need'這個名字來引用參數'need'字段的值。 – Bakuriu
謝謝你們,不知道那種語法! – cemulate