没有 unsafeCoerce 有没有办法获取子记录?

Is there any way to get subrecord without unsafeCoerce?

type Foo = {
  x :: Int,
  y :: Int
}

type Bar = {
  x :: Int
}

foo :: Foo
foo = {x:1,y:2}
bar :: Bar
bar = foo

Could not match type

()

with type

( y :: Int )

为什么这不可能?

我无法使用

type Bar a = {
  x :: Int | a
}

并且不想重新创建记录

bar = {x : foo.x}

unsafeCoerce是唯一的选择吗?

使用 unsafeCoerce 可能有什么问题?

如果您想编写函数来处理只有一些特定字段的记录,那么您可以改用空行:

bar :: forall r. { x :: Int | r } -> { x :: Int | r }
bar rec = rec

这仍然与 FooBar 同义词兼容。

然而,如果这也不好,你只是想 "forget" 关于 y 那么 unsafeCoerce 应该可以使用,只要你只强制 FooBar,并且不再返回。

我强烈建议使用别名 unsafeCoerce 而不是直接使用它:

forget :: Foo -> Bar
forget = Unsafe.Coerce.unsafeCoerce

即使你认为自己在按原则使用它,直接使用它也很容易出错。

就我个人而言,我只是创建一个没有字段的新记录,即使它涉及一些样板文件。