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

type Bar = {
  x :: Int
}

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

无法匹配类型

()

带类型

( y :: Int )

为什么这不可能?

我不能使用

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

并且不想重新创建记录

bar = {x : foo.x}

unsafeCoerce唯一的选择吗?

使用 可能有什么问题unsafeCoerce

4

1 回答 1

5

如果你想编写函数来处理只有一些特定字段的记录,那么你可以使用一个开放的行来代替:

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

这仍然与FooBar同义词兼容。

但是,如果这也不好,并且您只是想“忘记”,y那么unsafeCoerce应该可以使用,只要您只强制FooBar,而不是再次返回。

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

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

即使您认为自己以有原则的方式使用它,直接使用它也很容易出错。

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

于 2016-03-27T14:36:48.350 回答