假設我想表示具有常數c,一元函數符號f和謂詞P的一階語言的有限模型。我可以將載體表示爲列表m
,該常數作爲m
的元素,函數爲有序對m
元件(其可以經由一個輔助函數ap
被應用)的列表,和謂詞作爲滿足它的m
的元素的列表:如何在Haskell中編寫這個依賴類型的示例?
-- Models (m, c, f, p) with element type a
type Model a = ([a], a, [(a,a)], [a])
-- helper function application, assumes function is total
ap :: Eq a => [(a,b)] -> a -> b
ap ((x',y'):ps) x = if x == x' then y' else ap ps x
我然後可以構建特定的模型和模型操作。細節是不是我的問題很重要,只是類型的(但我已經包括了定義,所以你可以看到那裏的類型約束來自於):
unitModel :: Model()
unitModel = ([()],(), [((),())], [])
cyclicModel :: Int -> Model Int
cyclicModel n | n > 0 = ([0..n-1], 0, [(i, (i+1)`mod`n) | i<-[0..n-1]], [0])
-- cartesian product of models
productModel :: (Eq a, Eq b) => Model a -> Model b -> Model (a,b)
productModel (m1, c1, f1, p1) (m2, c2, f2, p2) = (m12, c12, f12, p12) where
m12 = [(x1,x2) | x1 <- m1, x2 <- m2]
c12 = (c1, c2)
f12 = [(x12, (ap f1 (fst x12), ap f2 (snd x12))) | x12 <- m12]
p12 = [x12 | x12 <- m12, elem (fst x12) p1 && elem (snd x12) p2]
-- powerset of model (using operations from Data.List)
powerModel :: (Eq a, Ord a) => Model a -> Model [a]
powerModel (m, c, f, p) = (ms, cs, fs, ps) where
ms = subsequences (sort m) -- all subsets are "normalized"
cs = [c]
fs = [(xs, nub (sort (map (ap f) xs))) | xs <- ms] -- "renormalize" the image of f
ps = [xs | xs <- ms, elem c xs]
現在,我想給名字所有的這些模型:
data ModelName = UnitModel
| CyclicModel Int
| Product ModelName ModelName
| Power ModelName
deriving (Show, Eq)
最後,我想編寫此代碼,每個名稱映射到模型,可以名稱:
model_of UnitModel = unitModel
model_of (CycleModel n) = cycleModel n
model_of (Product m1 m2) = productModel (model_of m1) (model_of m2)
model_of (Power m1) = powerModel (model_of m1)
我已經嘗試了許多方法來使這個工作,在定義ty的意義因此我可以使用這個model_of的定義,包括使用幻像類型,GADT和類型族 - 但還沒有找到一種方法來實現它。 (但是,再次,我是Haskell的新手。)可以這樣做嗎?我應該怎麼做?
你剛纔侵入我的Emacs怎麼我有同樣的答案准備好:) – Ankur
一個我想是與此類似,但沒有在該類型約束的方法構造函數類型,以便爲我解決一個問題 - 謝謝。但是我尋找其他方法的一個原因是感覺這樣的定義在關於其特定用途之一的太多信息中烘焙了:我可能還想編寫僅與名稱一起工作的代碼,其中額外的類型信息將是多餘的,比如一個同構測試'ModelName - > ModelName - > Bool'。有沒有辦法爲這些目的保留原始的ModelName定義,但仍然允許model_of? – lambdacalculator
data ErasedModel = forall t。 ErasedModel(ModelName t) - 不會推薦它,但:-) – sclv