榆树可扩展记录init

时间:2015-11-30 15:33:57

标签: elm

我试图创建一个装饰器类型来保持某个项目周围的状态。这个项目可能是电子邮件,新闻公告,提醒等等...我认为这样做会但我收到错误。

type alias Model a =
  {a | pinned : Bool, done : Bool, trunc : Bool}

init : a -> Model(a)
init cont = {cont | pinned <- False, done <- False, trunc <- False}

以下是编译器错误:

Detected errors in 1 module.
## ERRORS in .\.\Item.elm ######################################################

-- TYPE MISMATCH -------------------------------------------------- .\.\Item.elm

The type annotation for `init` does not match its definition.

20| init : a -> Model(a)
           ^^^^^^^^^^^^^
Could not unify user provided type variable `a`. The most likely cases are:

  1. The type you wrote down is too general. It says any type can go through
     but in fact only a certain type can.
  2. A type variable is probably being shared between two type annotations.
     They are treated as different things in the current implementation, so
     Try commenting out some type annotations and see what happens.

As I infer the type of values flowing through your program, I see a conflict
between these two types:

    a

    { d | done : a, pinned : b, trunc : c }

我想要装饰的类型是:

type alias Email =
  { from: String
  , to: String
  , title: String
  , body: String
  , date: String
  }

type alias Reminder =
  { body: String
  , created: String
  }

更改&#39;&lt; - &#39;到&#39; =&#39;我得到以下模糊的语法错误:

Detected errors in 1 module.
## ERRORS in .\.\Item.elm ######################################################

-- SYNTAX PROBLEM ------------------------------------------------- .\.\Item.elm

I ran into something unexpected when parsing your code!

21| init cont = { cont | pinned = False, done = False, trunc = False }
                                       ^
I am looking for one of the following things:

    a closing bracket '}'
    a field access like .name
    an expression
    an infix operator like (+)
    more letters in this name
    whitespace

1 个答案:

答案 0 :(得分:4)

我从您使用的语法中看到,这不是Elm 0.16,这是记录更新语法更改的版本。在您当前的Elm版本中,您可以这样做:

type alias Model a =
  {a | pinned : Bool, done : Bool, trunc : Bool}

init : a -> Model a -- the parentheses were superfluous so I removed them
init cont0 =
  let cont1 = { cont0 | pinned = False }
      cont2 = { cont1 | done = False }
      cont3 = { cont2 | trunc = False }
  in cont3

由于根据类型注释,您添加字段,而不是更新字段。遗憾的是,你一次只能添加一个字段,所以请原谅这种笨拙的语法。

请注意,在Elm 0.16 field addition syntax has been removed中。它没有得到太多使用,新人发现=<-非常混乱。因此,删除了字段添加,并将更新语法更改为使用=。这意味着在新版本的Elm中,您将无法以这种方式编写init函数。请参阅博客文章和邮件列表,了解使用可扩展记录重写程序的策略,以使用其他类型对事物进行建模。

举一个例子,说明如何将程序更改为仍可使用Elm 0.16 +:

type alias Model a =
  { submodel: a, pinned: Bool, done: Bool, trunc: Bool }

init : a -> Model a
init submodel = Module submodel False False False
-- This makes use of the generated record constructor
--  that came with the type alias definition.
-- You could also write: 
--  { submodel: submodel, pinned: False, done: False, trunc: False }