Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.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
Haskell 基本型有限域容器上的动态类型化_Haskell_Dynamic Typing - Fatal编程技术网

Haskell 基本型有限域容器上的动态类型化

Haskell 基本型有限域容器上的动态类型化,haskell,dynamic-typing,Haskell,Dynamic Typing,我在编写一个简单函数时遇到了一个问题,没有太多的重复,下面是一个简化的例子。我试图编写的真正程序是python中BI服务器的内存数据库端口。实际上,有更多不同的类型(大约8种)和更多的逻辑,它们大多可以表示为在多态类型上操作的函数,如向量a,但仍有一些逻辑必须处理不同类型的值 由于效率原因,单独包装每个值(使用[(Int,WrappedValue)]类型)不是一个选项-在实际代码中,我使用的是非固定向量 type Vector a = [(Int, a)] -- always sorted by

我在编写一个简单函数时遇到了一个问题,没有太多的重复,下面是一个简化的例子。我试图编写的真正程序是python中BI服务器的内存数据库端口。实际上,有更多不同的类型(大约8种)和更多的逻辑,它们大多可以表示为在多态类型上操作的函数,如向量a,但仍有一些逻辑必须处理不同类型的值

由于效率原因,单独包装每个值(使用[(Int,WrappedValue)]类型)不是一个选项-在实际代码中,我使用的是非固定向量

type Vector a = [(Int, a)] -- always sorted by fst

data WrappedVector = -- in fact there are 8 of them
      FloatVector (Vector Float)
    | IntVector (Vector Int)
    deriving (Eq, Show)

query :: [WrappedVector] -> [WrappedVector] -- equal length
query vectors = map (filterIndexW commonIndices) vectors
    where
        commonIndices = intersection [mapFstW vector | vector <- vectors]

intersection :: [[Int]] -> [Int]
intersection = head -- dummy impl. (intersection of sorted vectors)

filterIndex :: Eq a => [Int] -> Vector a -> Vector a
filterIndex indices vector = -- sample inefficient implementation
    filter (\(idx, _) -> idx `elem` indices) vector

mapFst :: Vector a -> [Int]
mapFst = map fst

-- idealy I whould stop here, but I must write repeat for all possible types
-- and kinds of wrapped containers and function this:

filterIndexW :: [Int] -> WrappedVector -> WrappedVector
filterIndexW indices vw = case vw of
    FloatVector v -> FloatVector $ filterIndex indices v
    IntVector   v -> IntVector $ filterIndex indices v

mapFstW :: WrappedVector -> [Int]
mapFstW vw = case vw of
    FloatVector v -> map fst v
    IntVector   v -> map fst v

-- sample usage of query
main = putStrLn $ show $ query [FloatVector [(1, 12), (2, -2)],
                                IntVector   [(2, 17), (3, -10)]]
type Vector a=[(Int,a)]--始终按fst排序
data WrappedVector=--实际上有8个
浮动向量(向量浮动)
|IntVector(向量Int)
推导(等式,显示)
查询::[WrappedVector]->[WrappedVector]——等长
查询向量=映射(filterIndexW CommonIndexs)向量
哪里
CommonIndex=交点[mapFstW向量|向量[Int]
交叉点=头部--虚拟输入(排序向量的交叉点)
filterIndex::Eq a=>[Int]->向量a->向量a
filterIndex Indexes vector=--示例实现
过滤器(\(idx,\)->idx`elem`index)向量
mapFst::向量a->[Int]
mapFst=map fst
--理想情况下,我可以到此为止,但我必须为所有可能的类型编写repeat
--包装容器的种类和功能如下:
filterIndexW::[Int]->WrappedVector->WrappedVector
filterIndexW指数vw=情况vw
FloatVector v->FloatVector$filterIndex v
IntVector v->IntVector$filterIndex索引v
mapFstW::WrappedVector->[Int]
mapFstW vw=案例vw
浮动向量v->映射fst v
IntVector v->映射fst v
--查询的示例用法
main=putStrLn$show$query[FloatVector[(1,12),(2,-2)],
IntVector[(2,17),(3,-10)]]

如何在没有像mapFstW和filterIndexW函数那样包装和展开的情况下表达这样的代码?

包装单个类型而不影响性能的标准选项是

{-# LANGUAGE GeneralizedNewtypeDeriving #-} -- so we can derive Num
newtype MyInt = My Int deriving (Eq,Ord,Show,Num)
newtype AType a = An a deriving (Show, Eq)
因为它只在类型级别上产生差异-数据表示是相同的,因为它都被编译掉了。您甚至可以指定值是未绑定的,但是…这对您没有帮助,因为您正在包装多个类型

真正的问题是,您试图用静态类型化语言表示动态类型化的解决方案。动态类型化的性能必然会受到影响,动态类型化在动态语言中是隐藏的,但在标记中是显式的

您有两种解决方案:

  • 接受动态类型比静态类型涉及更多的运行时检查,并接受丑陋
  • 拒绝动态类型的需要,接受多态类型整理所有代码并将类型检查转移到编译时和数据获取

  • 我觉得2是目前为止最好的解决方案,你应该放弃尝试列出你想要使用的所有类型的程序,而不是使用任何类型的程序。它简洁、清晰、高效。你检查有效性并处理一次,然后就不用担心了。

    如果你愿意使用一些编译器扩展,请解决这个问题这是你的问题

    {-# LANGUAGE ExistentialQuantification #-}
    {-# LANGUAGE StandaloneDeriving #-}
    module VectorTest where
    
    type PrimVector a = [(Int, a)]
    
    data Vector = forall a . Show a => Vector (PrimVector a)
    
    deriving instance Show Vector
    
    query :: [Vector] -> [Vector] -- equal length
    query vectors = map (filterIndex commonIndices) vectors
        where
            commonIndices = intersection [mapFst vector | vector <- vectors]
    
    intersection :: [[Int]] -> [Int]
    intersection = head -- dummy impl. (intersection of sorted vectors)
    
    filterIndex :: [Int] -> Vector -> Vector
    filterIndex indices (Vector vector) = -- sample inefficient implementation
        Vector $ filter (\(idx, _) -> idx `elem` indices) vector
    
    mapFst :: Vector -> [Int]
    mapFst (Vector l) = map fst l
    
    -- sample usage of query
    main = putStrLn $ show $ query [Vector [(1, 12), (2, -2)],
                                    Vector [(2, 17), (3, -10)]]
    

    这很好地概括了实际问题(有一点Data.Typeable的帮助),谢谢!很高兴听到这很有帮助!
    instance Show Vector where
        show (Vector v) = show v