gpt4 book ai didi

Haskell Data.List.Class 和语法

转载 作者:行者123 更新时间:2023-12-04 07:25:51 25 4
gpt4 key购买 nike

我正在尝试阅读 Haskell 包 Data.List.Class 的源代码。 (列表-0.4.2)。但我坚持使用一些语法。

开头是这样写的:

data ListItem l a =
Nil |
Cons { headL :: a, tailL :: l a }

我不熟悉第 3 行的语法。我猜这最后一行相当于 Cons a (l a) ???。但我不太确定。我注意到文件头说: {-# LANGUAGE FlexibleContexts, TypeFamilies #-} .

然后随着我的继续, type 有一个奇怪的用法。声明: type ItemM l :: * -> * ,我无法理解。
Data.List.Class
-- | A class for list types. Every list has an underlying monad.
class (MonadPlus l, Monad (ItemM l)) => List l where
type ItemM l :: * -> *
runList :: l a -> ItemM l (ListItem l a)
joinL :: ItemM l (l a) -> l a
cons :: a -> l a -> l a
cons = mplus . return

谁能帮忙解释一下这些是什么意思?我对 Data.List 有一个完美的理解,但是这个类型类的东西对我来说并不是很清楚。
我还搜索了有关使用 Data.List.{Class,Tree} 的 wiki、示例和/或教程,但似乎没有任何内容,除了代码附带的注释。这里有任何指示吗?

谢谢。

- 更新 -
第一个答案(@Chris)帮助我理解了 Kind 签名和 Record Syntax,这真的很有帮助。但是,就它如何捕获/定义 List 的行为以及它为熟悉的 Data.List 定义增加了什么值(value)而言,我仍然无法从整体上理解那段代码。这里有一些进一步的细节,其中只有两个实例语句。还有 Identity术语来自 import Data.Functor.Identity (Identity(..)) .你能帮忙解释一下这是什么类型类来捕捉我们通常知道的列表的特征吗?同样,我在网上搜索了它,但除了代码本身之外,实际上没有 Data.List.Class 的文档。有谁知道?

另外,是否有另一个使用 type 的示例? typeclass 约束中的语句类似于此示例中的内容?我搜索了 learnyouahaskell.com/(@Landei) 但找不到这样的例子。我假设 type 的用法这类似于您将如何使用 typedef '在 C++ 模板中定义'类型上的函数',对吗?

再次感谢。
instance List [] where
type ItemM [] = Identity
runList [] = Identity Nil
runList (x:xs) = Identity $ Cons x xs
joinL = runIdentity
cons = (:)

instance Functor m => Functor (ListItem m) where
fmap _ Nil = Nil
fmap func (Cons x xs) = Cons (func x) (fmap func xs)

最佳答案

记录语法
这个

data ListItem l a = Nil | Cons { headL :: a, tailL :: l a }
称为记录语法。当您猜测结构与您输入的相同时,您是正确的
data ListItem l a = Nil | Cons a (l a)
但是,您还可以获得两个访问器函数:
headL :: ListItem l a -> a
headL (Cons a _) = a

tailL :: ListItem l a -> l a
tailL (Cons _ as) = as
记录语法是语法糖——在这里它可以为您节省大约 4 行代码。您可以以正常方式进行模式匹配,如本段正上方的代码,或者您可以在模式匹配中使用记录语法:
safeHeadL :: ListItem l a -> Maybe a
safeHeadL Nil = Nothing
safeHeadL (Cons {headL = a}) = Just a
同样,这被取消为标准模式匹配。
亲切的签名
这个
class (MonadPlus l, Monad (ItemM l)) => List l where
type ItemM l :: * -> *
runList :: l a -> ItemM l (ListItem l a)
joinL :: ItemM l (l a) -> l a

cons :: a -> l a -> l a
cons = mplus . return
是一个类型族声明。线
  type ItemM l :: * -> *
是一种亲切的签名。当我们说某事有种 * ,我们的意思是它是一个基本类型,比如 IntFloat .说某事有种 * -> *意味着它是一个类型构造函数,即它接受一个类型并返回另一个类型。 Maybe类型构造函数具有这种签名:
Maybe :: * -> *
请记住 Maybe就其本身而言不是一种类型。它必须被赋予一个类型,然后它返回一个类型。给它 Int你会得到 Maybe Int .给它 Double你会得到 Maybe Double .
类型构造函数 ItemM l接受一个类型参数(类型 * )并返回一些类型 * .请注意,由于 l是种 * , 你有
ItemM :: * -> * -> *
ItemM接受两种类型,并返回一个类型(等效地,它接受一种类型并返回一个一元类型构造函数)。
通过在类中包含类型声明,您在类的所有实例中施加了约束, lItemM l必须与 l 匹配在 List l .不可能创建这些不匹配的类的实例。

关于Haskell Data.List.Class 和语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11770733/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com