Haskell "newtype" for type synonyms

I am doing something with SAT and I want to have both "and" and "or" sentences.

type AndClause = [Literal] type OrClause = [Literal] 

But I am having problems when I use them:

 instance Satisfiable AndClause where ... instance Satisfiable OrClause where ... 

Gives me "Duplicate instance declarations". These are types, not data or type constructors, so I don't think I can use newtype to accomplish what I want. Is there any solution?

+6
source share
1 answer

The problem is that it seems to you that you need two conflicting points at once:

  • You need different names for the same type
  • You want the compiler to understand these two types of names as belonging to different types

Based on the domain, I think that you certainly do not want to use type synonyms and that you need the actual new types (with the accompanying type constructors). If AndClause is a synonym for [Literal] , and OrClause is a synonym for [Literal] , by the transitive property, AndClause and OrClause are mutually synonymous. Therefore, the compiler has no reason to distinguish between them (thus, there can be no polymorphism).

What you really want are two different types that behave differently, for which newtype will only do fine:

 newtype AndClause = AndClause [Literal] newtype OrClause = OrClause [Literal] instance Satisfiable AndClause where satisfy (AndClause l:ls) = --... instance Satisfiable OrClause where satisfy (OrClause l:ls) = --... 

But, an even better idea might be to make it an algebraic data type:

 data Prop = And [Literal] | Or [Literal] instance Satisfiable Prop where satisfy (And l:ls) = --... satisfy (Or l:ls) = --... 

(Note that I am printing this from the compiler, but in principle this should be correct).

+21
source

Source: https://habr.com/ru/post/886023/


All Articles