为什么安全的部分函数使用Maybe而不是泛化为任何Monad

时间:2016-04-14 21:43:25

标签: haskell monads

我知道有些人认为fail是个错误,我明白为什么。 (似乎MonadPlus是为了取代它)。但只要它存在,似乎部分函数使用failpure代替JustNothing是有意义的。因为这可以让您完成目前可以执行的所有操作以及更多内容,因此safeHead之类的内容可以为您提供传统的Just / Nothing,或者您可以返回[x] / []

据我所知,MonadPlus似乎比使用fail更好。但是我不能确切地知道这一点,并且它也可能涉及拉入Prelude,这可能是一个好主意,但是比使用fail更大的改变。

所以我猜我的问题是为什么部分功能不能使用failMonadPlus,这两者似乎都比使用具体类型更好。

1 个答案:

答案 0 :(得分:8)

  

所以我猜我的问题是为什么部分功能不能使用failMonadPlus,这两者似乎都比使用具体类型更好。

嗯,我不能说出写作者的动机,但我当然也有同感。我在这里说的是,我们中的许多人都遵循一种思想流派,其中Maybe这样的具体类型将成为我们的默认选择,因为:

  1. 简单而具体;
  2. 它完美地模拟了域名;
  3. 它可以通常映射到您能想到的任何更抽象的解决方案。
  4. a -> Maybe b这样的类型完美地模拟了部分函数的概念,因为部分函数返回结果(Just b)或者它不会(Nothing),并且没有更好的区别(例如,没有不同类型的"虚无")。

    第3点可以用这个函数说明,它通常将Maybe a转换为Alternative的任何实例(MonadPlus的超类):

    import Control.Applicative
    
    fromMaybe :: Alternative f => Maybe a -> f a
    fromMaybe Nothing = empty
    fromMaybe (Just a) = pure a
    

    按照这种理念,你用Maybe来编写部分函数,​​如果你需要将结果放在其他Alternative实例中,那么你使用fromMaybe函数作为适配器。

    然而,可以反过来说,你可以这样做:

    safeHead :: Alternative f => [a] -> f a
    safeHead [] = empty
    safeHead (a:_) = pure a
    

    ...认为仅safeHead xs键入的内容比fromMaybe (safeHead xs)短。每个人都有自己的。