为什么我不能简化这种模式匹配?

时间:2016-03-17 13:28:26

标签: haskell

这很好用:

data Possibly a = LolNope | Yeppers a deriving (Eq, Show)

instance Functor Possibly where
    fmap f (Yeppers a) = Yeppers (f a)
    fmap _ LolNope = LolNope

重复最后一行中的LolNope看起来并不优雅。用以下内容替换最后一行不起作用:

fmap _ z = z  -- error: Couldn't match type ‘a’ with ‘b’ ...

这也不起作用:

fmap _ z@(_) = z  -- error: Couldn't match type ‘a’ with ‘b’ ...

为什么它们不起作用,是否有其他选择?

1 个答案:

答案 0 :(得分:7)

因为它们涉及不同的类型:

fmap f LolNope = LolNope
--               ^-- Possibly b
--     ^-- Possibly a
--   ^-- a -> b

当然,这两个LolNope的运行时表示在GHC中是相同的,但这还不够。它的表示甚至可以与Nothing()[]和其他无效构造函数重合,但不允许这些构造函数。

恕我直言,这是关于类型系统比实际需要更严格的一个很好的例子。

尽管存在静态约束,GHC运行时可能会选择重用LolNope :: Possibly aLolNope :: Possibly b的相同内存位置。 (我不记得它是否确实......)