Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell "newtype" for type synonyms

Tags:

types

haskell

I'm doing some stuff with SAT, and I want to have both "and" and "or" clauses.

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

But I'm running into problems when I use them:

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

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

like image 850
Xodarap Avatar asked Apr 15 '11 22:04

Xodarap


People also ask

What is a type synonym in Haskell?

From HaskellWiki. A type synonym is a new name for an existing type. Values of different synonyms of the same type are entirely compatible. In Haskell you can define a type synonym using type : type MyChar = Char.

What is the difference between type and data in Haskell?

Type and data type refer to exactly the same concept. The Haskell keywords type and data are different, though: data allows you to introduce a new algebraic data type, while type just makes a type synonym. See the Haskell wiki for details.

What does () mean in Haskell?

() is very often used as the result of something that has no interesting result. For example, an IO action that is supposed to perform some I/O and terminate without producing a result will typically have type IO () .

How are types used in Haskell?

In Haskell, every statement is considered as a mathematical expression and the category of this expression is called as a Type. You can say that "Type" is the data type of the expression used at compile time. To learn more about the Type, we will use the ":t" command.


1 Answers

The problem is that you seem to want two conflicting things at once:

  1. You want different names for the same type
  2. You want the compiler to understand those two type names as referring to different types

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

What you really want are two different types that behave differently, for which newtype will do just 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 this 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'm typing this away from a compiler, but it should basically be right).

like image 194
Jonathan Sterling Avatar answered Nov 15 '22 11:11

Jonathan Sterling