2016-11-27 11 views
2

ich Haskell bin mit und versuche, die folgend schreiben:Typ Constraints in Daten Erklärung Haskell

data Scale s = Scale s s 

Allerdings mag ich es machen, so dass s etwas sein muss, dass die Typklasse Num, wie Int oder Doppelt. Ist das mit Haskell und GHC möglich?

+1

Dies ist möglich, aber ist fast nie das, was Sie tun sollten. Im Allgemeinen ist es viel besser, die Bedingung "Num s" nur auf die Funktionen zu setzen, die sie tatsächlich benötigen. – Alec

+0

Alec, alle meine Funktionen mit der Skala benötigen die num-Bedingung. –

+0

@AviCaspe Es gibt sehr gute Gründe, dies nicht zu tun. Die Antwort enthält eine, aber es gibt andere. Sie sollten wirklich darüber nachdenken, die Einschränkungen genau dort zu platzieren, wo sie benötigt werden. – Carl

Antwort

11

Ja:

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

Allerdings ist es im Allgemeinen als Best-Practice-nicht dies zu tun. Setzen Sie die Num-Einschränkung stattdessen nur auf die Funktionen Scale s und die Num Einschränkung. Wenn Sie sich über solche Einschränkungen entspannt fühlen, können Sie die Invariante vorübergehend unterbrechen, wo es angemessen ist. z.B. Es ist üblich, eine Functor Instanz für einen solchen Typ zu wünschen, was unmöglich ist, wenn Sie den Konstruktor wie oben beschrieben einschränken.

4

Ich hatte eine ähnliche Situation mit Point Typ. Aber ich dachte nicht über Einschränkungen nach, ich dachte darüber nach, wie ich den Elementtyp meines Punktes verallgemeinern könnte. Dann habe ich verstanden, wenn ich Punkttyp wie diesen data Point a = Point a a habe, dann kann ich es Instanz von Functor, Applicative, Foldable und Traversable tun. Und ich kann Funktion nach Standart allgemeiner Art entwerfen. Zum Beispiel:

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

Und ich hatte Frage. Was ist los? :) Wenn ich Constraint hinzufüge (wie Sie gefragt haben), würde ich auf diese Weise nicht entwerfen können und ich würde viele Funktionen wie pointSub implementieren müssen.

Also, es gibt etwas zu denken :)

+0

Sie können sogar eine [Monad-Instanz] (http://hackage.haskell.org/package/transformers-0.5.1.0/docs/src/Data-Functor-Product.html#line-126) für [z ein Typ] (http://hackage.haskell.org/package/transformers-0.5.1.0/docs/Data-Functor-Product.html). –

+0

Ja, ich weiß, du hast Recht. Aber ich denke, es ist nicht interessant für dieses Beispiel :) – freestyle