繁体   English   中英

为什么Haskell [](列表)不是类型类?

[英]Why is Haskell [] (list) not a type class?

我正在编写一个Haskell函数,它以列表作为输入。 也就是说,没有理由它不能成为队列或出队,或任何允许我访问其“头部”及其“尾部”(并检查它是否为空)的东西。 所以[a]输入类型似乎太具体了。 但是AFAIK没有标准的库类型类可以捕获这个接口。 当然,我可以将我的函数包装在Data.Foldable.toList中并使其变为多态wrt可折叠,但这看起来不太正确(惯用)。

为什么没有标准的列表类型类? (为什么Haskell中的“容器”类型层次结构比我认为应该更少?)或者我错过了必要的东西?

给定的代数数据类型可以表示为其变形,一种称为教会编码的变换。 这意味着列表与其foldr同构:

type List a = forall b. (a -> b -> b) -> b -> b

fromList :: [a] -> List a
fromList xs = \f z -> foldr f z xs

toList :: List a -> [a]
toList l = l (:) []

foldr也刻画Foldable 您可以根据foldr定义foldMap ,反之亦然。

foldMap f = foldr (mappend . f) mempty
foldr f z t = appEndo (foldMap (Endo . f) t) z

foldMap :: Monoid m => (a -> m) -> [a] -> m表示列表是不足为奇的,因为列表是一个免费的幺半群。)换句话说, Foldable基本上给你toList as一类。 Foldable实例有一条通过它们的“路径”,可以走路给你一个列表; Foldable类型至少具有与列表一样多的结构。


关于你的疑虑:

它不像Foldable具有head / tail / isEmpty函数,这是我会发现更直观的。

null :: Foldable t => ta -> Bool是你的isEmpty ,你可以通过适当选择Monoid直接定义(一个安全版本) head

head :: Foldable t :: t a -> Maybe a
head = getFirst . foldMap (First . Just)

在我看来, tail有点棘手。 对于任意类型, tail甚至意味着什么并不明显。 你当然可以编写tail :: Foldable t => ta -> Maybe [a] (通过toList ing然后解散),但我认为任何类型Ttail :: T a -> Maybe (T a)都是定义的必须在结构上类似于列表(例如Seq )。 此外,根据我的经验,绝大多数你认为你需要访问列表tail毕竟是折叠的。

也就是说,抽象不可靠的类型偶尔会有用。 例如, megaparsec为(单态)标记流定义了一个Stream类,用作解析器的输入。

问题

让你的问题更具体,让我们问:

为什么不是类型类

class HasHeadAndTail t where
    head :: t a -> Maybe a
    tail :: t a -> Maybe (t a)
    isEmpty :: t a -> Bool

base库?

答案

此类仅适用于有序的线性容器。 MapSetHashMapHashTableTree都不是实例。 我甚至反对将SeqDList作为一个实例,因为该结构实际​​上有两个可能的“头”。

关于这个类的一个实例,我们还可以说什么呢? 我认为唯一的属性是如果isEmpty是False那么headtail应该是非Nothing 因此,isEmpty甚至不应该在类中,而是一个函数isEmpty :: HashHeadAndTail t => ta -> Bool ; isEmpty = isNothing . head isEmpty :: HashHeadAndTail t => ta -> Bool ; isEmpty = isNothing . head isEmpty :: HashHeadAndTail t => ta -> Bool ; isEmpty = isNothing . head

所以我的答案是:

  • 这个类在缺乏实例的情况下缺乏实用性。
  • 这个类缺乏有用的属性,缺乏属性的类经常被劝阻。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM