2017-03-02 74 views
2

可以說我有約束操縱包

class C1 t 

class C2 t 

注意到這裏:

C1 :: * -> Constraint 
C2 :: * -> Constraint 

我可以讓

class (C1 t, C2 t) => C3 t 
instance (C1 t, C2 t) => C3 t 

因此,我們有

C3 :: * -> Constraint 

指出,C3 t只有當有效C1 tC2 t是。

此外,如果我們加了一堆擴展:

{-# LANGUAGE TypeFamilies #-} 
{-# LANGUAGE MultiParamTypeClasses #-} 
{-# LANGUAGE ConstraintKinds #-} 
{-# LANGUAGE UndecidableSuperClasses #-} 
{-# LANGUAGE FlexibleInstances #-} 
{-# LANGUAGE FlexibleContexts #-} 
{-# LANGUAGE TypeOperators #-} 

我們甚至可以做更多的事情一般是這樣的:

class (c1 a, c2 a) => And c1 c2 a 
instance (c1 a, c2 a) => And c1 c2 a 

type C3 = C1 `And` C2 

而這按預期工作。

這不是限制,我希望能夠做的唯一的組合,例如,我想能夠約束結合兩個變量,說And2

class (c1 a b, c2 a b) => And2 c1 c2 a b 
instance (c1 a b, c2 a b) => And2 c1 c2 a b 

或添加額外約束第一個變量:

class (c1 a, c2 a b) => AddFirst c1 c2 a b 
instance (c1 a, c2 a b) => AddFirst c1 c2 a b 

當然有很多可能性。

現在不想推倒重來,我一直在尋找的constraints包,從中我引述:做​​類型類分爲不同的類型了一種新的,約束的

ConstraintKinds。

Eq :: * -> Constraint 
Ord :: * -> Constraint 
Monad :: (* -> *) -> Constraint 

隨着ConstraintKinds我們可以投入代碼有很多工具 沒有這樣尷尬的變通辦法處理這些新類型。

這看起來好像符合法案,但我有點迷失在文檔中。

constraints包是否符合我在本文中列出的內容?如果是這樣,你能舉一個例子嗎?如果沒有,是否還有其他軟件包用於約束處理,或者我應該自己將其填充到庫中?

回答

2

generics-sop中,這種約束操作通常是需要的,因爲其相當多的函數是通過約束參數化的。

因此,該庫包含一個模塊Generics.SOP.Constraint以及許多這些幫助類,特別是您的And。原則上可以增加更多,如果它們變得普遍有用的話。

據我所知,約束庫主要關注一個稍微不同的問題,即給你明確的字典和蘊含表示,爲你提供實用程序來證明GHC不能自動證明的類型類的事情。當然也可以將約束與這個庫結合起來,例如通過(&&&)。同樣,泛型-SOP也具有相似的功能(儘管功能要少得多,並且旨在減少功能),請參見Generics.SOP.Dict