[英]Am I thinking about and using singleton types in Haskell correctly?
我想創建幾個不兼容但相同的數據類型。 也就是說,我想要一個參數化類型Foo a
,以及諸如的函數
bar :: (Foo a) -> (Foo a) -> (Foo a)
實際上不關心什么a
是。 為了進一步澄清,我希望類型系統阻止我做
x :: Foo Int
y :: Foo Char
bar x y
雖然我同時並不真正關心Int
和Char
(我只關心他們不一樣)。
在我的實際代碼中,我有一個給定環上的多項式類型。 我實際上並不關心不確定性是什么,只要類型系統阻止我在t中用多項式添加多項式。 到目前為止,我已經通過創建一個類型類Indeterminate
,並將我的多項式類型參數化為...來解決這個問題
data (Ring a, Indeterminate b) => Polynomial a b
對於Ring
部分,這種方法感覺非常自然,因為我確實關心給定多項式結束的特定環。 對於Indeterminate
部分感覺非常有用,詳情如下。
上述方法工作正常,但感覺做作。 特別是這部分:
class Indeterminate a where
indeterminate :: a
data T = T
instance Indeterminate T where
indeterminate = T
data S = S
instance Indeterminate S where
indeterminate = S
(等等或許還有一些不確定的)。 這感覺奇怪和錯誤。 本質上,我試圖要求Indeterminate
實例是單身人士(在這個意義上 )。 奇怪的感覺是我可能會錯誤地攻擊這個問題的一個指標。 另一個原因是我最終不得不注釋我的Polynomial ab
因為實際的類型b
通常無法推斷(這並不奇怪,但仍然很煩人)。
有什么建議? 我應該繼續這樣做,還是我錯過了什么?
PS:如果我不立即投票或接受答案,請不要覺得被冒犯。 我將無法再回來查看幾天。
首先,我不確定這個:
data (Ring a, Indeterminate b) => Polynomial a b
......正在做你期望的事情。 關於data
定義的上下文並不是非常有用 - 請參閱此處的討論 ,原因可能就是為什么,其中大部分都是強制它們強制您添加額外的注釋而不實際提供許多其他類型保證。
其次,除了確保類型保持不同之外,你真的關心“不確定”參數嗎? 執行此類事情的一種非常標准的方法是所謂的幻像類型 - 實際上,類型構造函數中的參數未在數據構造函數中使用。 您永遠不會使用或需要幻像類型的值,因此函數可以像您想要的那樣具有多態性,例如:
data Foo a b = Foo b
foo :: Foo a b -> Foo a b
foo (Foo x) = Foo x
bar :: Foo a c -> Foo b c
bar (Foo x) = Foo x
baz :: Foo Int Int -> Foo Char Int -> Foo () Int
baz (Foo x) (Foo y) = Foo $ x + y
顯然這確實需要注釋,但僅限於您故意添加限制的地方。 否則,推理將對幻像類型參數正常工作。
在我看來,上述方法應該足以滿足您在這里所做的事情 - 單例類型的業務主要是通過創建值的類型代理來彌合更復雜的類型級別的東西和常規的價值級別計算之間的差距。 。 例如,這可以用於標記具有指示其基礎的類型的向量,或用物理單位標記數值 - 這兩種情況下注釋具有更多意義而不僅僅是“不確定的稱為X”。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.