榆树中的多态记录类型

时间:2018-09-20 02:57:49

标签: polymorphism record elm

榆树有以下可能吗?

func : a -> {a | id : Int}
func x = { x | id = 123 }

由于a多态的,因此无法编译;它认为可以是任何东西,包括非记录类型。如何告诉编译器a是一种记录类型,但是我们不知道其中的任何字段? (老实说,{a | id : Int}就足够了。)

我尝试过...

type alias Record a = {a}
func : Record a -> { a | id : Int }

func : {a} -> {a | id : Int}
func x = { x | id = 123 }

两者均因语法错误而失败。是否可以对Elm说“这种类型是唱片,但我什么都不知道”?

要在下面答复:

  

如果它是一个没有任何特定字段的记录,那么您将无法像它一样做任何记录,因此似乎无法表达出来。

在我的示例中,我试图用未知字段的记录来做类似记录的事情,所以说对它们无能为力是不正确的。

  

您不能将字段动态添加到记录中。

我不是在记录中动态添加字段,而是创建与现有记录匹配的新记录,只是它具有一个值为id的{​​{1}}字段。

  

那不是记录所做的事情,可能是因为如果已经有一个id字段,那将真的很尴尬。

这似乎是您推理的真实内容,但我认为这并非令人信服。为什么那会很尴尬?看来以这种方式工作是迄今为止最明显的工作方式?

  

如果这不是您想要的,那么看来这是XY问题的情况

放在一边,但是每次我遇到Elm字体系统的烦恼/弱点时,都是我的错而不是Elms。

3 个答案:

答案 0 :(得分:5)

如果它是一个没有任何特定字段的记录,那么您将无法像它一样做任何记录,因此似乎无法表达出来。

您不能动态地将字段添加到记录中。那不是记录所做的事情,可能是因为如果a已经有一个id字段,那确实很尴尬。因此,为了分配id,您需要知道记录中有一个id字段。因此,该函数的正确类型是:

func : {a | id : Int} -> {a | id : Int}

如果这不是您想要的,那么似乎是the XY problem

的情况

答案 1 :(得分:5)

否,Elm无法在没有指定任何字段的情况下使用类型注释来指示类型是记录。但是,即使没有类型注释,Elm也没有语法可以执行您想要的操作。 { a | id = 123 } record update 语法,它不支持在记录中添加字段(并且从Elm 0.19开始,也不支持更改字段的类型)

据我所知,Elm没有允许您生成带有附加字段的记录副本的语法。

答案 2 :(得分:1)

以上答案是正确的,也是更惯用的回答,但是我认为您可以通过使用新字段定义记录的类型别名来完成您要执行的操作。当然,您必须为所有可能的记录类型定义联合类型C

type alias A = { a : String }
type alias B = { a : Int }
type C = Foo A
       | Bar B

type alias D = { a : C, d : Int }
fn : C -> Int -> D 
fn a y = D a y