这个榆树构造的名称是什么:类型X = X {...}?

时间:2018-05-29 10:13:32

标签: syntax elm

我试图理解这个榆树构造:

> item = Item { name = "abc", data  = "def" } 
Item { name = "abc", data = "def" } : Repl.Item

> item.name
-- TYPE MISMATCH --------------------------------------------- repl-temp-000.elm

`item` does not have a field named `name`.

6|   item.name
     ^^^^^^^^^ The type of `item` is:

    Item

Which does not contain a field named `name`.
  • 它类似于记录,但行为却截然不同。
  • 它对于定义递归数据模型很有用。
  • class MyHttpServletRequestWrapper extends HttpServletRequestWrapper { private byte[] body; public MyHttpServletRequestWrapper(HttpServletRequest request) { super(request); try { body = IOUtils.toByteArray(request.getInputStream()); } catch (IOException ex) { body = new byte[0]; } } @Override public ServletInputStream getInputStream() throws IOException { new DelegatingServletInputStream(new ByteArrayInputStream(body)); } } public class DelegatingServletInputStream extends ServletInputStream { private final InputStream sourceStream; private boolean finished = false; /** * Create a DelegatingServletInputStream for the given source stream. * * @param sourceStream the source stream (never {@code null}) */ public DelegatingServletInputStream(InputStream sourceStream) { this.sourceStream = sourceStream; } /** * Return the underlying source stream (never {@code null}). */ public final InputStream getSourceStream() { return this.sourceStream; } @Override public int read() throws IOException { int data = this.sourceStream.read(); if (data == -1) { this.finished = true; } return data; } @Override public int available() throws IOException { return this.sourceStream.available(); } @Override public void close() throws IOException { super.close(); this.sourceStream.close(); } @Override public boolean isFinished() { return this.finished; } @Override public boolean isReady() { return true; } @Override public void setReadListener(ReadListener readListener) { throw new UnsupportedOperationException(); } } 不同,它不提供"构造函数"。
  • 我在Elm Syntax指南中找不到它。
  • 我无法弄清楚如何访问其字段:
export const getShifts = () => dispatch => {
console.log('Fetching list of shifts for user...');
const request = API.get("StaffAPI", "/shifts", {
    headers: {
           'Accept': 'application/json',
           'Content-Type': 'application/json',
    }
})
.then(response =>
    dispatch({type: 'SHIFTS_LOAD_SUCCESS', response})
)
.catch(err =>
    dispatch({type: 'SHIFTS_LOAD_FAIL'})
)
}
  • 这个结构如何调用?
  • 如何访问包含的字段?

1 个答案:

答案 0 :(得分:6)

这是一个Union Type,只有一个构造函数,它恰好以Record作为唯一的类型参数。

类型名称和构造函数名称都是type Item = Foo { name : String, data : String } 这一事实是一个常见的习惯用语,但没有任何意义。它可以很容易地是任何其他有效的构造函数名称:

type alias ItemContents = { name : String, data : String }

type Item = Item ItemContents

出于实际目的,为内部记录类型使用类型别名会很有用,这样您就可以更简洁地拉出值。如果你稍微移动一下:

getItemContents : Item -> ItemContents
getItemContents (Item contents) = contents

您可以提供一个返回内部内容的函数:

> item = Item { name = "abc", data  = "def" }
Item { name = "abc", data = "def" } : Repl.Item
> contents = getItemContents item
{ name = "abc", data = "def" } : Repl.ItemContents
> contents.name
"abc" : String

现在它可以像这个REPL示例一样使用:

{{1}}