Data structures 有没有办法做得更多;“动态”;Haskell中的数据构造函数?
是否有一些Haskell扩展支持创建比GADT更复杂的数据构造函数 假设我想创建一个数据结构,它是一个有序列表,并且有一个类似于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 ->
(:)
的数据构造函数,可以处理列表,类型签名为:
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]