为什么Haskell 98的标准类不如Haskell 1.3?

29 haskell standard-library

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

例如,该标记首先由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
Run Code Online (Sandbox Code Playgroud)

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

这与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
Run Code Online (Sandbox Code Playgroud)

这也是Haskell 2010中的定义.我对此定义存在以下问题:

  • MonadZero并且MonadPlus走了 他们是有用的课程.
  • 如果一个符号模式匹配失败...

    • Haskell 1.3使用zero.左零法适用(zero >>= k = zero),所以你知道应该发生什么.
    • Haskell 98使用fail msg,在msgGHC的情况下编译生成的位置.任何事情都可能发生,无法保证其语义.因此,它对用户来说并不是很重要.因此,Haskell 98的标记中模式匹配失败的行为是不可预测的!
  • 名称不太通用(例如mapvs. fmap).这不是一个大问题,但它是我眼中的刺.


总而言之,我认为这些变化不是最好的.事实上,我认为它们是从Haskell 1.4向后退一步.为什么Haskell 98会改变这些东西,为什么会这样呢?


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

  • " fail允许定位错误." 仅适用于程序员,仅适用于运行时.(unportable!)错误消息并不是您要解析的内容.如果你真的关心它,你应该明确地跟踪它.我们现在Control.Failure从failure包中获得了更好的工作(failure x主要表现得像zero).
  • "有太多的课程使开发和使用太难." 课程太少会破坏他们的法律,这些法律和类型一样重要.
  • "实例限制功能更容易学习." 那么为什么不存在SimplePrelude,大多数类被删除了?对于学生来说,这只是一个神奇的宣言,他们可以管理这么多.(也许{-# LANGUAGE RebindableSyntax #-}也需要,但同样,学生们非常擅长复制粘贴的东西.)
  • "受实例限制的功能使错误更具可读性." 我使用fmap往往比多map,那么为什么不map和listMap呢?

Don*_*art 24

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

Haskell 98涉及对语言的大量简化(其中大部分已经被逆转).目标是改进Has​​kell作为教学语言,并做出相对保守的选择.

见例如

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

在:Haskell的历史

和:

Haskell 98绝不是Haskell的最后一个版本.相反,我们设计它知道新的语言扩展(多参数类型类,通用和存在量化,模式保护等等)正在顺利进行.但是,Haskell 98将具有特殊的状态:意图是Haskell编译器将继续支持Haskell 98(给定一个适当的标志),即使在定义了更高版本的语言之后,因此名称`Haskell 98'将引用一种固定,稳定的语言.

在:Haskell98报告

因此,事情被简化,目标是生成更简单的标准.

  • 很棒的答案!在第二个来源中,有一个很好的变化列表.我想我应该看看1997年到1998年之间的邮件列表档案.我已经发现了一些有趣的电子邮件,例如SPJ [首先喜欢`NPlusKPatterns`](http://code.haskell.org/~dons/haskell -1990-2000/msg00582.html),并[六年后讨厌它](http://code.haskell.org/~dons/haskell-1990-2000/msg03476.html). (2认同)