2016-11-27 66 views
2

我使用Haskell和嘗試寫如下:在報關資料的Haskell類型約束

data Scale s = Scale s s 

不過,我希望把它使s必須的東西的Num類型的類,如int或雙。有可能使用Haskell和GHC嗎?

+1

這是可能的,但幾乎從來沒有你應該做的。將'Num s'約束僅放在實際需要的函數上通常要好得多。 – Alec

+0

亞歷克,我所有使用比例的函數都需要num的約束。 –

+0

@AviCaspe有很好的理由不這樣做。答案包含一個,但也有其他答案。你真的應該考慮的只是把需要它們的約束。 – Carl

回答

11

是:

{-# LANGUAGE GADTs #-} 
data Scale s where 
    Scale :: Num s => s -> s -> Scale s 

然而,人們普遍認爲是最佳做法做到這一點。相反,將Num約束僅限於使用Scale s和需要約束的函數。放寬這些約束條件可以讓你在適當的時候暫時破除不變量;例如通常希望Functor這種類型的實例,如果您像上面那樣約束構造函數,這是不可能的。

4

我和Point類型有類似的情況。但我認爲沒有約束條件,我想過如何對我的觀點的元素類型進行概括。然後我明白,如果我有像這樣的點類型data Point a = Point a a那麼我可以做它Functor,Applicative,Foldable和Traversable的實例。我可以通過標準的一般方式來設計功能。例如:

dist :: Floating a => Point a -> Point a -> a 
dist a b = sqrt $ sum $ (^2) <$> ((-) <$> a <*> b) 

我有問題。到底是怎麼回事? :)如果我添加約束(如你所問)我不會這樣設計,我需要實現很多功能,如pointSub

所以,有些事情需要考慮:)

+0

事實上,你甚至可以使一個[單子實例(http://hackage.haskell.org/package/transformers-0.5.1.0/docs/src/Data-Functor-Product.html#line-126)的[例如一個類型](http://hackage.haskell.org/package/transformers-0.5.1.0/docs/Data-Functor-Product.html)。 –

+0

是的,我知道,你是對的。但我一點也沒有intrestiing這個例子:) – freestyle