我似乎陷入了该语言的一个有趣的边缘情况。解释我想要做什么很棘手,所以让我用代码来编写它:
data Foobar x =
Foo1 {field1 :: x, field2 :: String} |
Foo2 {field1 :: x, field3 :: Int} |
Foo3 { field4 :: Bool} |
Foo4 { field2 :: String, field4 :: Bool}
如您所见,某些构造函数依赖于x
,但其他构造函数则不然。我正在尝试编写一个类似于 fmap
的函数:
transform :: (x -> y) -> Foobar x -> Foobar y
transform fn foobar =
case foobar of
Foo1 {} -> foobar {field1 = fn (field1 foobar)}
Foo2 {} -> foobar {field1 = fn (field1 foobar)}
_ -> foobar
如您所见,整齐的记录语法让我不必重建整个构造函数,仅在需要的地方应用 fn
。不幸的是,当零位置需要fn
时,这种情况就会中断。在这种情况下(即最终的替代方案),表达式无法进行类型检查。我很清楚为什么失败 - 但我对如何修复这个问题感到困惑。
显然我可以直接写出整个事情。这适用于这个简化的示例,但我尝试编写的实际应用程序要大得多。 (大约 25 个构造函数,其中一些具有 15 个以上的字段。)
有人对如何修复这个故障有什么好主意吗?
最佳答案
一种解决方案(为了节省打字)是使用记录通配符:
{-# LANGUAGE RecordWildCards #-}
-- ...
case foobar of
Foo4 {..} -> Foo4 {..}
关于haskell - 强制幻影型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21649512/