Haskell 就地多态快速排序中的数组类型参数
我想实现一个多态快速排序。我想具体说明一下Haskell 就地多态快速排序中的数组类型参数,haskell,Haskell,我想实现一个多态快速排序。我想具体说明一下 IArray UArray a=>[a]->[a]中的类型a和sts(stus数组Int a)中的类型相同。我该怎么做 {-# LANGUAGE FlexibleContexts #-} module Quicksort where import Control.Monad.ST (ST) import Data.Array.ST (runSTUArray, newListArray, STUArray) import Data.Array.IArr
IArray UArray a=>[a]->[a]
中的类型a和sts(stus数组Int a)
中的类型相同。我该怎么做
{-# LANGUAGE FlexibleContexts #-}
module Quicksort where
import Control.Monad.ST (ST)
import Data.Array.ST (runSTUArray, newListArray, STUArray)
import Data.Array.IArray (elems)
import Data.Array.Unboxed (UArray, IArray)
quicksort :: IArray UArray a => [a] -> [a]
quicksort l = elems $ runSTUArray $
do newListArray (0, 9) l :: ST s (STUArray s Int a)
通过启用
ScopedTypeVariables
并在顶级类型签名中,您可以进入下一个错误:
quicksort :: forall a. IArray UArray a => [a] -> [a]
然后,您会发现您的STUArray
不是MArray
的一个实例,因为有一个用于任意a
。如果将其设置为Int
,它将编译
当然,明显没有这样一个实例的原因是,一个未绑定数组只能包含一个不可执行的值,这将是一个基本类型的值,一个详尽的列表,您可以在中查看。您可以使用
Data.Constraint.Forall
使此操作适用于任何不可执行的对象。然而,由于该机制的工作方式,它可能不是最有效的。一种更烦人但可能更好的方法是编写一个类似于MArray
的类,使用一个需要s
参数的构造函数
{-# Language MultiParamTypeClasses, ScopedTypeVariables, ConstraintKinds,
FlexibleInstances, FlexibleContexts, UndecidableInstances, TypeOperators #-}
module QS where
import Control.Monad.ST (ST, runST)
import Data.Constraint (Dict (..), (:-) (..))
import Data.Constraint.Forall (Forall, inst)
import Data.Array.ST (runSTUArray, newListArray, STUArray, MArray)
import Data.Array.IArray (elems)
import Data.Array.Unboxed (UArray, IArray)
type UnboxF a s = MArray (STUArray s) a (ST s)
class UnboxF a s => UnboxC a s
instance UnboxF a s => UnboxC a s
marrayDict :: Forall (UnboxC a) => Dict (UnboxC a s)
marrayDict = case inst :: Forall (UnboxC a) :- UnboxC a s of
Sub x -> x
quicksort :: forall a. (IArray UArray a, Forall (UnboxC a)) => [a] -> [a]
quicksort l = elems $ runSTUArray
( case marrayDict :: Dict (UnboxC a s) of { Dict ->
do
newListArray (0,9) l
} :: forall s. ST s (STUArray s Int a))
test :: [Char] -> [Char]
test = quicksort
当然,这可以通过额外的限制得到改善。导入
Data.Constraint for all
,定义类型unbxf a s=MArray(stu数组s)a(ST s)
,类unbxf a s=>unbxc a s
,实例unbxf a s=>unbxc a s
,为all(unbxc a)添加约束
添加到函数中,并根据需要使用inst
。@d我发现这个注释很难理解。具体地说,您指的是什么inst
?有关更多详细信息,请参阅我的答案。