Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Data structures 有没有办法做得更多;“动态”;Haskell中的数据构造函数?_Data Structures_Haskell_Constructor - Fatal编程技术网

Data structures 有没有办法做得更多;“动态”;Haskell中的数据构造函数?

Data structures 有没有办法做得更多;“动态”;Haskell中的数据构造函数?,data-structures,haskell,constructor,Data Structures,Haskell,Constructor,是否有一些Haskell扩展支持创建比GADT更复杂的数据构造函数 假设我想创建一个数据结构,它是一个有序列表,并且有一个类似于(:)的数据构造函数,可以处理列表,类型签名为: data MyOrdList a where (>>>) :: (Ord a) -> a -> MyOrdList a -> MyOrdList a 但是我希望(>>>)有一个特定的行为,比如: (>>>) :: (Ord a) => a ->

是否有一些Haskell扩展支持创建比GADT更复杂的数据构造函数

假设我想创建一个数据结构,它是一个有序列表,并且有一个类似于
(:)
的数据构造函数,可以处理列表,类型签名为:

data MyOrdList a where
    (>>>) :: (Ord a) -> a -> MyOrdList a -> MyOrdList a
但是我希望
(>>>)
有一个特定的行为,比如:

(>>>) :: (Ord a) => a -> [a] -> [a]
x >>> [] = [x] 
x >>> xs = low ++ [x] ++ high 
  where low  = filter (<x) xs
      high = filter (>x) xs
(>>>)::(Ord a)=>a->[a]->[a]
x>>[]=[x]
x>>>xs=低+++[x]++高
其中low=过滤器(x)xs
因此,结构将始终是一个有序结构。(我现在不知道这是否是一个好的实践,我只是提供了一个最简单的例子,让我了解我想要的行为类型)

当然,我可以使用函数
(>>>)
,但这样我就没有模式匹配和其他好处了,因为它是一个数据构造函数


有什么方法可以这样做吗?

您可以将
:>>>
作为数据构造函数,但必须将其隐藏以保留不变量。请注意,您可以在
render
中对其进行模式匹配:

module MyOrdList (mkMyOrdList,MyOrdList,render) where

import Data.List

import qualified Data.ByteString as BS

data MyOrdList a
  = EmptyDataList
  | (:>>>) a (MyOrdList a)
  deriving (Show)

mkMyOrdList [] = EmptyDataList
mkMyOrdList xs = y :>>> mkMyOrdList ys
  where y = minimum xs
        ys = delete y xs 

render :: (Show a) => MyOrdList a -> String
render EmptyDataList = "<empty>"
render (x :>>> xs) = (show x) ++ " -> " ++ render xs
样本输出:

54 -> 57 -> 64 -> 98 -> 131 -> 146 -> 147 -> 148 -> 190 -> 250 -> <empty>
54->57->64->98->131->146->147->148->190->250->。为了简单起见,我在这里使用标准列表作为“后端”

您可以这样使用它:

{-# LANGUAGE ViewPatterns #-}

import MyOrdList

ordlength :: MyOrdList a -> Int
ordlength (ordview -> OrdNil) = 0
ordlength (ordview -> OrdCons x xs) = 1 + ordlength xs
作品:

*Main> ordlength $ 2 >>> 3 >>> 1 >>> emptyOrdList 
3
*Main> 2 >>> 3 >>> 1 >>> emptyOrdList 
List [1,2,3]
因此,您的类型是抽象的,列表只能由
emptyOrdList
(>>>)
构建,但您仍然有一些模式匹配的便利性

{-# LANGUAGE ViewPatterns #-}

import MyOrdList

ordlength :: MyOrdList a -> Int
ordlength (ordview -> OrdNil) = 0
ordlength (ordview -> OrdCons x xs) = 1 + ordlength xs
*Main> ordlength $ 2 >>> 3 >>> 1 >>> emptyOrdList 
3
*Main> 2 >>> 3 >>> 1 >>> emptyOrdList 
List [1,2,3]