这很好用:
data Possibly a = LolNope | Yeppers a deriving (Eq, Show)
instance Functor Possibly where
fmap f (Yeppers a) = Yeppers (f a)
fmap _ LolNope = LolNope
Run Code Online (Sandbox Code Playgroud)
LolNope在最后一行重复看起来并不优雅.用以下内容替换最后一行不起作用:
fmap _ z = z -- error: Couldn't match type ‘a’ with ‘b’ ...
Run Code Online (Sandbox Code Playgroud)
这也不起作用:
fmap _ z@(_) = z -- error: Couldn't match type ‘a’ with ‘b’ ...
Run Code Online (Sandbox Code Playgroud)
他们为什么不工作,有没有其他选择?
因为它们涉及不同类型:
fmap f LolNope = LolNope
-- ^-- Possibly b
-- ^-- Possibly a
-- ^-- a -> b
Run Code Online (Sandbox Code Playgroud)
当然,这两个LolNopes 的运行时表示在GHC中是相同的,但这还不够.它的表现甚至可以与重合Nothing,(),[],和其他无参构造函数却没有那些被允许.
恕我直言,这是关于类型系统比实际需要更严格的一个很好的例子.
尽管静态约束,则该GHC运行时可能会选择重新使用相同的内存位置LolNope :: Possibly a和LolNope :: Possibly b.(我不记得它是否确实......)