Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to state that a type variable in a newtype statement is of a type that belongs to some type class?

Suppose that I have this newtype:

newtype SomeType a = SomeType { foo :: OtherType a }

I want to ensure that a is showable (belongs to the type class Show x).

How do I ensure that? (Is it even possible?)

Bonus points: am I using the terminology correctly?

like image 420
Lay González Avatar asked Mar 21 '23 08:03

Lay González


2 Answers

It is possible with the DatatypeContexts extension, but it is strongly discouraged:

newtype Show a => SomeType a = SomeType { foo :: Maybe a }

It is recommended to put the constraint on the functions that use SomeType or use GADTs. See the answers to these questions for more information.

Alternative for deprecated -XDatatypeContext?

DatatypeContexts Deprecated in Latest GHC: Why?

Basically, it doesn't add anything useful and it makes you have to put constraints where they wouldn't otherwise be necessary.

like image 77
David Young Avatar answered Apr 30 '23 11:04

David Young


To demonstrate @David's answer in a small example, imagine you're implementing another incarnation of a balanced binary tree. Of course keys must be Ordered, so you add a constraint to the type declaration:

data Ord k => Tree k v = Tip | Bin k v (Tree k v) (Tree k v)

Now this constraint infects every other signature everywhere you're using this type, even when you don't really need to order keys. It wouldn't probably be a bad thing (after all, you'll need to order them at least somewhere – otherwise, you aren't really using this Tree) and it definitely doesn't break the code, but still makes it less readable, adds noise and distracts from important things.

empty :: Ord k => Tree k v

singleton :: Ord k => k -> v -> Tree k v

find :: Ord k => (v -> Bool) -> Tree k v -> Maybe v

instance Ord k => Functor (Tree k)

In all of these signatures the constraint could be omitted without any problems.

like image 26
Yuuri Avatar answered Apr 30 '23 12:04

Yuuri