如何评估Haskell中的一些"数据"定义

Lan*_*ard 1 haskell

我正在看一些例子来看看更复杂的data定义是如何工作的,例如......

data DualMap a b = DualMap (Map a b) (Map b a)
data Store s a = Store (s -> a) s deriving Functor
data Fold a b = forall x . Fold (x -> a -> x) x (x -> b)
data Pair a b = Pair !a !b
type Rule m a = (m -> a) -> a
data RingZipper a = RingZipper {
    before :: V.Vector a,
    focus  :: a,
    after  :: V.Vector a
} deriving(Eq, Generic, NFData)
Run Code Online (Sandbox Code Playgroud)

我对其中一些问题有一些简单的问题.

一,[a] a [a]这里的含义:

data Universe a = Universe [a] a [a]
Run Code Online (Sandbox Code Playgroud)

接下来,不确定以下是如何工作的.似乎用一种奇怪的方式从所有相同的元素中创建一个列表.我的意思是我不明白传递意味着什么BExpr.

data BExpr = BoolConst Bool
           | Not BExpr
           | BBinary BBinOp BExpr BExpr
           | RBinary RBinOp AExpr AExpr
Run Code Online (Sandbox Code Playgroud)

那就是这个.

接下来,想知道这里有什么[a] [(a,a)]意义,或者它是如何解决的.

data Digraph a = DG [a] [(a,a)] deriving (Eq,Ord,Show)
Run Code Online (Sandbox Code Playgroud)

其他一些我对...没有疑问

type Monomial coefficient exponent  = (coefficient, exponent)
Run Code Online (Sandbox Code Playgroud)

https://github.com/dmjio/miso/blob/master/src/Miso/Router.hs

data Router a where
  RChoice       :: Router a -> Router a -> Router a
  RCapture      :: FromHttpApiData x => (x -> Router a) -> Router a
  RQueryParam   :: (FromHttpApiData x, KnownSymbol sym)
                   => Proxy sym -> (Maybe x -> Router a) -> Router a
  RQueryParams  :: (FromHttpApiData x, KnownSymbol sym)
                   => Proxy sym -> ([x] -> Router a) -> Router a
  RQueryFlag    :: KnownSymbol sym
                   => Proxy sym -> (Bool -> Router a) -> Router a
  RPath         :: KnownSymbol sym => Proxy sym -> Router a -> Router a
  RPage         :: a -> Router a
Run Code Online (Sandbox Code Playgroud)

最后从这里开始,如何选择MergeL sa sb avs. MergeR sa sb a,我没有看到它.

data MergeState sa sb a
  = MergeL sa sb a
  | MergeR sa sb a
  | MergeLeftEnded sb
  | MergeRightEnded sa
  | MergeStart sa sb
Run Code Online (Sandbox Code Playgroud)

Lor*_*nzo 7

代数数据类型

代数数据类型是您想要查看的,它们可用于定义数据,例如树,代数表达式和解析指令.

  • data Universe a = Universe [a] a [a]

这定义了一个新的数据类型Universe,它包含类型的数据a(可以是任何类型),并使用列表,元素和另一个列表构造.它并没有说太多,我不能想出你何时使用它的例子,但如果你有一个我可以解释给你.(编辑:看第一条评论)重要的是要注意你可以用它进行模式匹配,所以你可以有一个如下的函数:

    f :: Universe a        -> a
    f (Universe _ 0 _)      = 0
    f (Universe (x:xs) z ys = x
Run Code Online (Sandbox Code Playgroud)
  • data BExpr = BoolConst Bool | Not BExpr | BBinary BBinOp BExpr BExpr | RBinary RBinOp AExpr AExpr

这再次定义了一种递归的新数据类型,它是最常用的类型.管道|构造函数的意思是"或",因为您的类型BExpr可以是:

  • BoolConst Bool :布尔常量(True/False),在其他类型中定义
  • Not BExpr :否定另一种表达方式
  • 一些其他表达式包含一个运算符和两个表达式来应用它

想一个更简单的例子,想一想

Data Tree a = Leaf a | Node (Tree a) a (Tree a)
Run Code Online (Sandbox Code Playgroud)

这就是大多数树的定义方式:您的数据可以是Leaf,也可以是包含两棵树和一些数据的节点.

查看这两个链接以获取更多信息: Haskell Wiki:代数数据类型 Haskell学校:评估数据类型

  • data Digraph a = DG [a] [(a,a)] deriving (Eq,Ord,Show) 这与它完全相同Universe a,它包含一些数据,并且构造它给它一个列表[a]和一个元组列表(a,a).同样,您可以使用模式匹配.

对于最后一个,他们再次使用不同的方法来调用该类型的构造函数

  • `Universe [a] a [a]`肯定看起来像列表[zipper](https://wiki.haskell.org/Zipper),即带有"聚焦元素"的列表.这个名字并不是令人回味的,但这种模式非常熟悉:左边的元素,右边的元素,右边的元素. (2认同)