0
votes

Suppose i have some type like:

newtype Foo a b = Foo { getFoo :: SomeStructure b }

I.e. a is a phantom type used only for compile-time checks.

However, I don't want to use the phantom type everywhere. It's not universally useful in my code. So I would like to do something like:

type FooUnrestricted b = Foo Anything b

What should I use in place of Anything? Do I need some language extensions?

Edit: I realized I could simply use () and it would answer my question. But the actual point is that I have functions that place constraints on a and I would like them to be always satisfied.

3
Maybe you could use coerce?Rufflewind

3 Answers

3
votes

One option is to use an existential type:

data UnrestrictedFoo b where
  Unrestricted :: Foo a b -> UnrestrictedFoo b

In some other contexts, it may make sense to use a rank 2 type instead.

newtype UnrestrictedFoo b = UnrestrictedFoo (forall a . Foo a b)
1
votes

You're probably looking for undefined at type level to make a stub for types. This was already discussed here: Undefined at the type level

So you can define your own data type and make instances for it of any type classes you use. If you want to lower number of instances you need to implement, you can use some standard data types like Void or even Proxy (). The latter is better because it has more instances.

http://hackage.haskell.org/package/base-4.9.0.0/docs/Data-Void.html

http://hackage.haskell.org/package/base-4.9.0.0/docs/Data-Proxy.html

1
votes

I agree that () is the best type to use here, as it conveys that you don't care about the type, but if you want it to satisfy your code constraints, you could newtype it and derive the needed instances trivially when you need them.