在 Thinking Functionly with Haskell(第 45 页)中,Richard Bird 说有 6 个类型为
Maybe a -> Maybe a
的函数,尽管他只提到了 5 个。
应用于
的函数只能返回Nothing
或Nothing
。 应用于undefined
的函数只能返回Just x
或Nothing
或Just x
。关键是我们对此一无所知 基础类型,因此无法发明新值。这使得六个 所有可能的功能。undefined
我数到七:
first, second, third, fourth, fifth, sixth, seventh :: Maybe a -> Maybe a
first (Just x) = Just x
second (Just x) = Nothing
third (Just x) = undefined
fourth Nothing = Nothing
fifth Nothing = undefined
sixth undefined = Nothing
seventh undefined = undefined
一个相关的难题是,当我尝试将其中三个定义放在一个函数下时,我收到编译错误“模式匹配是多余的”。删除三行中的任何一行都会使其消失
foo :: Maybe a -> Maybe a
foo (Just x) = Nothing
foo Nothing = undefined
foo undefined = Nothing
你的函数不是total函数,每次都取一个case。这意味着未涵盖的情况会出现错误。
所以本质上如果你写:
first (Just x) = Just x
是:
first (Just x) = Just x
first _ = error "case not covered"
因此,您需要涵盖两种情况的组合:
Just x
或Nothing
,从而乘以每种情况的可能性。
另一个问题是
undefined
中的 sixth undefined = Nothing
不 检查该项是否未定义:它只是一个名为 undefined
的变量。所以相当于sixth x = Nothing
。
因此,这基本上为
Just x
留下了三个选项:Just x
、Nothing
和 undefined
/error
,以及 Nothing
的两个选项:Nothing
和未定义,所以:
first (Just x) = Just x
first Nothing = Nothing
second (Just x) = Just x
second Nothing = undefined
third (Just x) = Nothing
third Nothing = Nothing
fourth (Just x) = Nothing
fourth Nothing = undefined
fifth (Just x) = undefined
fifth Nothing = Nothing
sixth (Just x) = undefined
sixth Nothing = undefined