29

在 Haskell 98 之前,有 Haskell 1.0 到 1.4。看到这些年来的发展非常有趣,因为功能被添加到标准化 Haskell 的最早版本中。

例如,do-notation 首先由Haskell 1.3标准化(发布于 1996-05-01)。在 中Prelude,我们找到以下定义(第 87 页):

-- Monadic classes

class  Functor f  where
    map         :: (a -> b) -> f a -> f b

class  Monad m  where
    (>>=)       :: m a -> (a -> m b) -> m b
    (>>)        :: m a -> m b -> m b
    return      :: a -> m a

    m >> k      = m >>= \_ -> k

class  (Monad m) => MonadZero m  where
    zero        :: m a

class  (MonadZero m) => MonadPlus m where
    (++)        :: m a -> m a -> m a

在 Haskell 1.4 中可以找到相同的定义。我对此确实有一些问题(例如,这里还没有发生MonadPlus改革),但总的来说,这是一个非常好的定义。

这与 Haskell 98 非常不同,Haskell 98 有以下定义:

-- Monadic classes


class  Functor f  where
    fmap              :: (a -> b) -> f a -> f b


class  Monad m  where
    (>>=)  :: m a -> (a -> m b) -> m b
    (>>)   :: m a -> m b -> m b
    return :: a -> m a
    fail   :: String -> m a

        -- Minimal complete definition:
        --      (>>=), return
    m >> k  =  m >>= \_ -> k
    fail s  = error s

这也是 Haskell 2010 中的定义。我对这个定义有以下问题:

  • MonadZero并且MonadPlus消失了。它们是有用的课程。
  • 如果 do-notation 中的模式匹配失败...

    • Haskell 1.3 使用zero. 左零定律适用 ( zero >>= k = zero),所以你知道应该发生什么。
    • Haskell 98 使用fail msg,如果msg是 GHC,编译器生成的位置。任何事情都可能发生,不能保证它的语义。因此,它对用户来说并不是什么功能。因此,Haskell 98 的 do-notation 中模式匹配失败的行为是不可预测的!
  • 名称不太通用(例如mapvs. fmap)。不是什么大问题,但它是我眼中的一根刺。


总而言之,我认为这些变化并不是最好的。事实上,我认为它们比 Haskell 1.4 倒退了一步。为什么 Haskell 98 改变了这些东西,为什么会这样?


顺便说一句,我可以想象以下防御:

  • fail允许定位错误。” 仅适用于程序员,并且仅在运行时。(不可移植!)错误消息并不完全是您要解析的内容。如果你真的关心它,你应该明确地跟踪它。我们现在Control.Failurefailure包中获得,它在这方面做得更好(failure x表现得大多像zero)。
  • “有太多的类使开发和使用变得太难了。” 类太少违反了它们的规律,而这些规律与类型一样重要。
  • “实例限制功能更容易学习。” 那么为什么没有一个SimplePrelude替代,大部分类都被删除了呢?对于学生来说,这只是一个神奇的宣言,他们可以做到这一点。(也许{-# LANGUAGE RebindableSyntax #-}也需要,但同样,学生们非常擅长复制粘贴。)
  • “实例限制函数使错误更具可读性。” 我使用fmap的频率比mapmap,那为什么不listMap呢?
4

1 回答 1

24

为什么 Haskell 98 改变了这些东西,为什么会这样?

Haskell 98 对语言进行了很多简化(其中大部分已经被颠倒了)。目标是改进 Haskell 作为一种教学语言,并做出相对保守的选择。

参见例如

我们认为 Haskell 98 是一个相当保守的设计。例如,当时多参数类型类被广泛使用,但 Haskell 98 只有单参数类型类(Peyton Jones et al., 1997)。

在:Haskell 的历史

和:

Haskell 98 绝不会是 Haskell 的最后一个版本。相反,我们设计它时知道新的语言扩展(多参数类型类、通用和存在量化、模式保护等)正在顺利进行中。然而,Haskell 98 将有一个特殊的地位:其目的是即使在定义了该语言的更高版本之后,Haskell 编译器仍将继续支持 Haskell 98(给定一个适当的标志),因此名称“Haskell 98”将指代一种固定的、稳定的语言。

在:Haskell98 报告

因此,事情被简化了,目标是产生一个更简单的标准。

于 2013-09-12T10:29:29.383 回答