创建基于以下的队列类型Seq:
import Data.Sequence
type Queue v = Seq v
现在我想编写一个返回队列第一个元素(“头”)的函数。从我阅读和谷歌搜索的所有内容看来,应该是这样的:
qhead :: Queue v -> v
qhead Empty = error "empty sequence"
qhead (x :<| xs) = x
赛皮特:
不在范围内:数据构造函数 ':<|'
好的,我是这样做的:
qhead' :: ViewL v -> v
qhead' EmptyL = error "empty sequence"
qhead' (x :< xs) = x
qhead :: Queue v -> v
qhead q = qhead' $ viewl q
但也许可以做一些更笨拙的事情?直接用typeQueue来比较,不介意一些笨蛋ViewL吗?还是这么犹太?
完整代码:
import Data.Sequence
type Queue v = Seq v
qhead' :: ViewL v -> v
qhead' EmptyL = error "empty sequence"
qhead' (x :< xs) = x
qhead :: Queue v -> v
qhead q = qhead' $ viewl q
{-
*R.QTree> qhead $ fromList [12,13,14,15]
12
-}
根据您的评论,您拥有
PatternSynonyms.该库
Data.Sequence不导出 type 的构造函数Seq,只导出同义词。这意味着如果不支持同义词,您将无法将模式与此类型匹配。根本没有什么可比较的。因此,您要么必须启用对同义词的支持,要么使用丑陋的变通方法。在我看来,您拒绝延期并不是基于他们的误解。Haskell 中的语言扩展不是额外的库或魔术技巧。它们和其他任何东西一样都是语言的一部分。
它们只是被禁用,以免迫使人们不断地重写旧代码。一些扩展稍微改变了现有结构的含义,一些需要额外的解释,等等。如果这些功能只是愚蠢地添加到语言中(就像几乎所有其他语言一样),那么随着编译器的每次更新,您将不得不修复损坏的代码。为了防止这种情况发生,Haskell 提前做出了“按需”添加新功能的决定。
我再重复一遍:上述逻辑仅适用于现有项目。如果您已经有一堆五年前编写的代码,那么您可以使用现代编译器,只是不要包含新的扩展。
但是对于全新的代码,不包括扩展是没有意义的:你只是无缘无故地强迫自己用一种有十年历史的语言编写,仅此而已。没有任何收获。