tin*_*lyx 8 syntax haskell typeclass
我正在尝试阅读Haskell包Data.List.Class的源代码.(列表0.4.2).但我坚持使用一些语法.
在开头,它写着:
data ListItem l a =
Nil |
Cons { headL :: a, tailL :: l a }
Run Code Online (Sandbox Code Playgroud)
我不熟悉第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
Run Code Online (Sandbox Code Playgroud)
谁能帮忙解释一下这些意思?我对Data.List有一个完美的理解,但这种类型的东西对我来说并不是很清楚.我还搜索了有关使用Data.List.{Class,Tree}的wiki,示例和/或教程,但似乎没有任何内容,除了代码附带的注释.这里有什么指示?
谢谢.
- 更新 - 第一个答案(@Chris)帮助我理解了Kind签名和Record Syntax,这非常有用.但是,就如何捕获/定义List的行为以及它为熟悉的Data.List定义添加的值而言,我仍然无法理解整个代码片段.以下是一些进一步的细节,其中只有两个实例语句.这个Identity词也来自import Data.Functor.Identity (Identity(..)).你能帮我解释一下这是类型类的功能,以便像我们通常所知的那样捕获列表的特征吗?我再次在网上搜索它,但除了代码本身之外,Data.List.Class确实没有文档.有谁知道?
另外,type在类型类约束中是否有另一个使用类似于此示例中的语句的示例?我搜索了learnyouahaskell.com/(@Landei),但找不到这样的例子.我假设type这里的用法类似于你typedef在C++模板中用's'来定义'类型上的函数',对吗?
再次感谢.
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)
Run Code Online (Sandbox Code Playgroud)
这个
data ListItem l a = Nil | Cons { headL :: a, tailL :: l a }
Run Code Online (Sandbox Code Playgroud)
被称为记录语法.当您猜测结构与您键入的结构相同时,您就是正确的
data ListItem l a = Nil | Cons a (l a)
Run Code Online (Sandbox Code Playgroud)
但是,您还可以获得两个访问器功能:
headL :: ListItem l a -> a
headL (Cons a _) = a
tailL :: ListItem l a -> l a
tailL (Cons _ as) = as
Run Code Online (Sandbox Code Playgroud)
记录语法是语法糖 - 这里它可以节省大约4行代码.您可以按照正常方式进行模式匹配,如本段正上方的代码,或者您可以在模式匹配中使用记录语法:
safeHeadL :: ListItem l a -> Maybe a
safeHeadL Nil = Nothing
safeHeadL (Cons {headL = a}) = Just a
Run Code Online (Sandbox Code Playgroud)
再次,这是对标准模式匹配的贬低.
这个
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
Run Code Online (Sandbox Code Playgroud)
是一个类型家庭声明.这条线
type ItemM l :: * -> *
Run Code Online (Sandbox Code Playgroud)
是一种亲切的签名.当我们说某事有点时*,我们的意思是它是一种基本类型,如Int或Float.要说某种东西有种* -> *意味着它是一种类型构造函数,即它需要一个类型并返回另一种类型.
该Maybe类型的构造有这样的签名:
Maybe :: * -> *
Run Code Online (Sandbox Code Playgroud)
请记住,Maybe它本身不是一种类型.它必须被赋予一个类型,然后它返回一个类型.给它Int,你得到Maybe Int.给它Double,你得到Maybe Double.
类型构造函数ItemM l采用类型参数(类型*)并返回类似的东西*.请注意,既然l是实物*,你就有
ItemM :: * -> * -> *
Run Code Online (Sandbox Code Playgroud)
ie ItemM接受两种类型,并返回一个类型(等效地,它采用一种类型并返回一元类型的构造函数).
通过在类中包含类型声明,您可以强加约束,即在类的所有实例中,lin ItemM l必须与lin 匹配List l.创建一个不匹配的类实例是不可能的.
| 归档时间: |
|
| 查看次数: |
577 次 |
| 最近记录: |