Я пытаюсь смоделировать следующий простой Scala ADT в Haskell:
sealed trait Value
sealed trait Literal < Value
case object Null extends Literal
case class IntLiteral(value: Int) extends Literal
case class Variable(name: String) < Value
Я моделирую черту Literal
:
Prelude> data Literal = Null | IntLiteral Int deriving (Show, Eq)
Все идет нормально:
Prelude> Null
Null
Prelude> Null == IntLiteral 3
False
Prelude> IntLiteral 3 == IntLiteral 3
True
Теперь я пытаюсь представить Variable
:
data Value = Literal | Variable String deriving (Show, Eq)
Почему это не работает?
Prelude> Null == Variable "foo"
<interactive>:3:9: error:
• Couldn't match expected type ‘Literal’ with actual type ‘Value’
• In the second argument of ‘(==)’, namely ‘Variable "foo"’
In the expression: Null == Variable "foo"
In an equation for ‘it’: it = Null == Variable "foo"
Literal
является конструктором типаValue
; он не принимает аргументов и не связан с типомLiteral
. Вы имели в видуdata Value = Literal Literal | ...
Literal Null == Variable "foo"
? - person melpomene   schedule 08.07.2017data Value = Literal Literal | Variable String deriving (Show, Eq)
, я получаю ожидаемый результат:(Literal $ IntLiteral 3) == Variable "foo"
=>False
. Я не уверен, что понимаю разницу между конструкторомLiteral
и типомLiteral
. - person Bob T   schedule 08.07.2017data .. =
и после каждого последующего|
является именем конструктора (значение). Остальные относятся к типам. Синтаксис примерно такой:data T .. = K1 T11 T12 ... | K2 T21 T22 ... | K3 T31 T32 ...| ...
- person chi   schedule 08.07.2017Null
относится к типуLiteral
,Variable "foo"
относится к типуValue
. также может быть конструктор данныхLiteral
, не связанный с одноименным типом. это просто разные вещи, живущие в разных пространствах имен в Haskell. если вы пишетеdata Value = Literal Literal | ...
, первоеLiteral
— это имя конструктора данных (в этом случае создает значения типаValue
), второе — это имя типа. - person Will Ness   schedule 08.07.2017