简体   繁体   English

Haskell“newtype”用于类型同义词

[英]Haskell “newtype” for type synonyms

I'm doing some stuff with SAT, and I want to have both "and" and "or" clauses. 我正在做SAT的一些事情,我希望同时拥有“和”和“或”条款。

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. 它们是类型,而不是数据或类型构造函数,所以我认为我不能使用newtype来做我想要的。 Is there any solution? 有什么解决方案吗?

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. 如果AndClause[Literal]的同义词,而OrClause[Literal]的同义词,那么通过传递属性, AndClauseOrClause是相互同义的。 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可以做得很好:

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). (请注意,我正在远离编译器输入它,但它基本上应该是正确的)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM